interval_set_algo.hpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. /*-----------------------------------------------------------------------------+
  2. Copyright (c) 2008-2010: Joachim Faulhaber
  3. +------------------------------------------------------------------------------+
  4. Distributed under the Boost Software License, Version 1.0.
  5. (See accompanying file LICENCE.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. +-----------------------------------------------------------------------------*/
  8. #ifndef BOOST_ICL_INTERVAL_SET_ALGO_HPP_JOFA_081005
  9. #define BOOST_ICL_INTERVAL_SET_ALGO_HPP_JOFA_081005
  10. #include <boost/next_prior.hpp>
  11. #include <boost/icl/detail/notate.hpp>
  12. #include <boost/icl/detail/relation_state.hpp>
  13. #include <boost/icl/type_traits/identity_element.hpp>
  14. #include <boost/icl/type_traits/is_map.hpp>
  15. #include <boost/icl/type_traits/is_total.hpp>
  16. #include <boost/icl/type_traits/is_combinable.hpp>
  17. #include <boost/icl/concept/set_value.hpp>
  18. #include <boost/icl/concept/map_value.hpp>
  19. #include <boost/icl/interval_combining_style.hpp>
  20. #include <boost/icl/detail/element_comparer.hpp>
  21. #include <boost/icl/detail/interval_subset_comparer.hpp>
  22. #include <boost/icl/detail/associated_value.hpp>
  23. namespace boost{namespace icl
  24. {
  25. namespace Interval_Set
  26. {
  27. //------------------------------------------------------------------------------
  28. // Lexicographical comparison on ranges of two interval container
  29. //------------------------------------------------------------------------------
  30. template<class LeftT, class RightT>
  31. bool is_element_equal(const LeftT& left, const RightT& right)
  32. {
  33. return subset_compare
  34. (
  35. left, right,
  36. left.begin(), left.end(),
  37. right.begin(), right.end()
  38. ) == inclusion::equal;
  39. }
  40. template<class LeftT, class RightT>
  41. bool is_element_less(const LeftT& left, const RightT& right)
  42. {
  43. return element_compare
  44. (
  45. left, right,
  46. left.begin(), left.end(),
  47. right.begin(), right.end()
  48. ) == comparison::less;
  49. }
  50. template<class LeftT, class RightT>
  51. bool is_element_greater(const LeftT& left, const RightT& right)
  52. {
  53. return element_compare
  54. (
  55. left, right,
  56. left.begin(), left.end(),
  57. right.begin(), right.end()
  58. ) == comparison::greater;
  59. }
  60. //------------------------------------------------------------------------------
  61. // Subset/superset compare on ranges of two interval container
  62. //------------------------------------------------------------------------------
  63. template<class IntervalContainerT>
  64. bool is_joinable(const IntervalContainerT& container,
  65. typename IntervalContainerT::const_iterator first,
  66. typename IntervalContainerT::const_iterator past)
  67. {
  68. if(first == container.end())
  69. return true;
  70. typename IntervalContainerT::const_iterator it_ = first, next_ = first;
  71. ++next_;
  72. while(next_ != container.end() && it_ != past)
  73. if(!icl::touches(key_value<IntervalContainerT>(it_++),
  74. key_value<IntervalContainerT>(next_++)))
  75. return false;
  76. return true;
  77. }
  78. template<class LeftT, class RightT>
  79. bool is_inclusion_equal(const LeftT& left, const RightT& right)
  80. {
  81. return subset_compare
  82. (
  83. left, right,
  84. left.begin(), left.end(),
  85. right.begin(), right.end()
  86. ) == inclusion::equal;
  87. }
  88. template<class LeftT, class RightT>
  89. typename enable_if<mpl::and_<is_concept_combinable<is_interval_set, is_interval_map, LeftT, RightT>,
  90. is_total<RightT> >,
  91. bool>::type
  92. within(const LeftT&, const RightT&)
  93. {
  94. return true;
  95. }
  96. template<class LeftT, class RightT>
  97. typename enable_if<mpl::and_<is_concept_combinable<is_interval_set, is_interval_map, LeftT, RightT>,
  98. mpl::not_<is_total<RightT> > >,
  99. bool>::type
  100. within(const LeftT& sub, const RightT& super)
  101. {
  102. int result =
  103. subset_compare
  104. (
  105. sub, super,
  106. sub.begin(), sub.end(),
  107. super.begin(), super.end()
  108. );
  109. return result == inclusion::subset || result == inclusion::equal;
  110. }
  111. template<class LeftT, class RightT>
  112. typename enable_if<is_concept_combinable<is_interval_map, is_interval_map, LeftT, RightT>,
  113. bool>::type
  114. within(const LeftT& sub, const RightT& super)
  115. {
  116. int result =
  117. subset_compare
  118. (
  119. sub, super,
  120. sub.begin(), sub.end(),
  121. super.begin(), super.end()
  122. );
  123. return result == inclusion::subset || result == inclusion::equal;
  124. }
  125. template<class LeftT, class RightT>
  126. typename enable_if<is_concept_combinable<is_interval_set, is_interval_set, LeftT, RightT>,
  127. bool>::type
  128. within(const LeftT& sub, const RightT& super)
  129. {
  130. int result =
  131. subset_compare
  132. (
  133. sub, super,
  134. sub.begin(), sub.end(),
  135. super.begin(), super.end()
  136. );
  137. return result == inclusion::subset || result == inclusion::equal;
  138. }
  139. template<class LeftT, class RightT>
  140. typename enable_if<mpl::and_<is_concept_combinable<is_interval_map, is_interval_set, LeftT, RightT>,
  141. is_total<LeftT> >,
  142. bool>::type
  143. contains(const LeftT&, const RightT&)
  144. {
  145. return true;
  146. }
  147. template<class LeftT, class RightT>
  148. typename enable_if<mpl::and_<is_concept_combinable<is_interval_map, is_interval_set, LeftT, RightT>,
  149. mpl::not_<is_total<LeftT> > >,
  150. bool>::type
  151. contains(const LeftT& super, const RightT& sub)
  152. {
  153. int result =
  154. subset_compare
  155. (
  156. super, sub,
  157. super.begin(), super.end(),
  158. sub.begin(), sub.end()
  159. );
  160. return result == inclusion::superset || result == inclusion::equal;
  161. }
  162. template<class LeftT, class RightT>
  163. typename enable_if<is_concept_combinable<is_interval_set, is_interval_set, LeftT, RightT>,
  164. bool>::type
  165. contains(const LeftT& super, const RightT& sub)
  166. {
  167. int result =
  168. subset_compare
  169. (
  170. super, sub,
  171. super.begin(), super.end(),
  172. sub.begin(), sub.end()
  173. );
  174. return result == inclusion::superset || result == inclusion::equal;
  175. }
  176. template<class IntervalContainerT>
  177. bool is_dense(const IntervalContainerT& container,
  178. typename IntervalContainerT::const_iterator first,
  179. typename IntervalContainerT::const_iterator past)
  180. {
  181. if(first == container.end())
  182. return true;
  183. typename IntervalContainerT::const_iterator it_ = first, next_ = first;
  184. ++next_;
  185. while(next_ != container.end() && it_ != past)
  186. if(!icl::touches(key_value<IntervalContainerT>(it_++),
  187. key_value<IntervalContainerT>(next_++)))
  188. return false;
  189. return true;
  190. }
  191. } // namespace Interval_Set
  192. namespace segmental
  193. {
  194. template<class Type>
  195. inline bool joinable(const Type& _Type, typename Type::iterator& some, typename Type::iterator& next)
  196. {
  197. // assert: next != end && some++ == next
  198. return touches(key_value<Type>(some), key_value<Type>(next))
  199. && co_equal(some, next, &_Type, &_Type);
  200. }
  201. template<class Type>
  202. inline void join_nodes(Type& object, typename Type::iterator& left_,
  203. typename Type::iterator& right_)
  204. {
  205. typedef typename Type::interval_type interval_type;
  206. interval_type right_interval = key_value<Type>(right_);
  207. object.erase(right_);
  208. const_cast<interval_type&>(key_value<Type>(left_))
  209. = hull(key_value<Type>(left_), right_interval);
  210. }
  211. template<class Type>
  212. inline typename Type::iterator
  213. join_on_left(Type& object, typename Type::iterator& left_,
  214. typename Type::iterator& right_)
  215. {
  216. //CL typedef typename Type::interval_type interval_type;
  217. // both left and right are in the set and they are neighbours
  218. BOOST_ASSERT(exclusive_less(key_value<Type>(left_), key_value<Type>(right_)));
  219. BOOST_ASSERT(joinable(object, left_, right_));
  220. join_nodes(object, left_, right_);
  221. return left_;
  222. }
  223. template<class Type>
  224. inline typename Type::iterator
  225. join_on_right(Type& object, typename Type::iterator& left_,
  226. typename Type::iterator& right_)
  227. {
  228. //CL typedef typename Type::interval_type interval_type;
  229. // both left and right are in the map and they are neighbours
  230. BOOST_ASSERT(exclusive_less(key_value<Type>(left_), key_value<Type>(right_)));
  231. BOOST_ASSERT(joinable(object, left_, right_));
  232. join_nodes(object, left_, right_);
  233. right_ = left_;
  234. return right_;
  235. }
  236. template<class Type>
  237. typename Type::iterator join_left(Type& object, typename Type::iterator& it_)
  238. {
  239. typedef typename Type::iterator iterator;
  240. if(it_ == object.begin())
  241. return it_;
  242. // there is a predecessor
  243. iterator pred_ = it_;
  244. if(joinable(object, --pred_, it_))
  245. return join_on_right(object, pred_, it_);
  246. return it_;
  247. }
  248. template<class Type>
  249. typename Type::iterator join_right(Type& object, typename Type::iterator& it_)
  250. {
  251. typedef typename Type::iterator iterator;
  252. if(it_ == object.end())
  253. return it_;
  254. // there is a successor
  255. iterator succ_ = it_;
  256. if(++succ_ != object.end() && joinable(object, it_, succ_))
  257. return join_on_left(object, it_, succ_);
  258. return it_;
  259. }
  260. template<class Type>
  261. typename Type::iterator join_neighbours(Type& object, typename Type::iterator& it_)
  262. {
  263. join_left (object, it_);
  264. return join_right(object, it_);
  265. }
  266. template<class Type>
  267. inline typename Type::iterator
  268. join_under(Type& object, const typename Type::value_type& addend)
  269. {
  270. //ASSERT: There is at least one interval in object that overlaps with addend
  271. typedef typename Type::iterator iterator;
  272. typedef typename Type::interval_type interval_type;
  273. typedef typename Type::value_type value_type;
  274. std::pair<iterator,iterator> overlap = object.equal_range(addend);
  275. iterator first_ = overlap.first,
  276. end_ = overlap.second,
  277. last_ = end_; --last_;
  278. iterator second_= first_; ++second_;
  279. interval_type left_resid = right_subtract(key_value<Type>(first_), addend);
  280. interval_type right_resid = left_subtract(key_value<Type>(last_) , addend);
  281. object.erase(second_, end_);
  282. const_cast<value_type&>(key_value<Type>(first_))
  283. = hull(hull(left_resid, addend), right_resid);
  284. return first_;
  285. }
  286. template<class Type>
  287. inline typename Type::iterator
  288. join_under(Type& object, const typename Type::value_type& addend,
  289. typename Type::iterator last_)
  290. {
  291. //ASSERT: There is at least one interval in object that overlaps with addend
  292. typedef typename Type::iterator iterator;
  293. typedef typename Type::interval_type interval_type;
  294. typedef typename Type::value_type value_type;
  295. iterator first_ = object.lower_bound(addend);
  296. //BOOST_ASSERT(next(last_) == this->_set.upper_bound(inter_val));
  297. iterator second_= boost::next(first_), end_ = boost::next(last_);
  298. interval_type left_resid = right_subtract(key_value<Type>(first_), addend);
  299. interval_type right_resid = left_subtract(key_value<Type>(last_) , addend);
  300. object.erase(second_, end_);
  301. const_cast<value_type&>(key_value<Type>(first_))
  302. = hull(hull(left_resid, addend), right_resid);
  303. return first_;
  304. }
  305. } // namespace segmental
  306. namespace Interval_Set
  307. {
  308. using namespace segmental;
  309. template<class Type, int combining_style>
  310. struct on_style;
  311. template<class Type>
  312. struct on_style<Type, interval_combine::joining>
  313. {
  314. typedef on_style type;
  315. typedef typename Type::interval_type interval_type;
  316. typedef typename Type::iterator iterator;
  317. inline static iterator handle_inserted(Type& object, iterator inserted_)
  318. { return join_neighbours(object, inserted_); }
  319. inline static iterator add_over
  320. (Type& object, const interval_type& addend, iterator last_)
  321. {
  322. iterator joined_ = join_under(object, addend, last_);
  323. return join_neighbours(object, joined_);
  324. }
  325. inline static iterator add_over
  326. (Type& object, const interval_type& addend)
  327. {
  328. iterator joined_ = join_under(object, addend);
  329. return join_neighbours(object, joined_);
  330. }
  331. };
  332. template<class Type>
  333. struct on_style<Type, interval_combine::separating>
  334. {
  335. typedef on_style type;
  336. typedef typename Type::interval_type interval_type;
  337. typedef typename Type::iterator iterator;
  338. inline static iterator handle_inserted(Type&, iterator inserted_)
  339. { return inserted_; }
  340. inline static iterator add_over
  341. (Type& object, const interval_type& addend, iterator last_)
  342. {
  343. return join_under(object, addend, last_);
  344. }
  345. inline static iterator add_over
  346. (Type& object, const interval_type& addend)
  347. {
  348. return join_under(object, addend);
  349. }
  350. };
  351. template<class Type>
  352. struct on_style<Type, interval_combine::splitting>
  353. {
  354. typedef on_style type;
  355. typedef typename Type::interval_type interval_type;
  356. typedef typename Type::iterator iterator;
  357. inline static iterator handle_inserted(Type&, iterator inserted_)
  358. { return inserted_; }
  359. inline static iterator add_over
  360. (Type& object, const interval_type& addend, iterator last_)
  361. {
  362. iterator first_ = object.lower_bound(addend);
  363. //BOOST_ASSERT(next(last_) == this->_set.upper_bound(inter_val));
  364. iterator it_ = first_;
  365. interval_type rest_interval = addend;
  366. add_front(object, rest_interval, it_);
  367. add_main (object, rest_interval, it_, last_);
  368. add_rear (object, rest_interval, it_);
  369. return it_;
  370. }
  371. inline static iterator add_over
  372. (Type& object, const interval_type& addend)
  373. {
  374. std::pair<iterator,iterator> overlap = object.equal_range(addend);
  375. iterator first_ = overlap.first,
  376. end_ = overlap.second,
  377. last_ = end_; --last_;
  378. iterator it_ = first_;
  379. interval_type rest_interval = addend;
  380. add_front(object, rest_interval, it_);
  381. add_main (object, rest_interval, it_, last_);
  382. add_rear (object, rest_interval, it_);
  383. return it_;
  384. }
  385. };
  386. template<class Type>
  387. void add_front(Type& object, const typename Type::interval_type& inter_val,
  388. typename Type::iterator& first_)
  389. {
  390. typedef typename Type::interval_type interval_type;
  391. typedef typename Type::iterator iterator;
  392. // If the collision sequence has a left residual 'left_resid' it will
  393. // be split, to provide a standardized start of algorithms:
  394. // The addend interval 'inter_val' covers the beginning of the collision sequence.
  395. // only for the first there can be a left_resid: a part of *first_ left of inter_val
  396. interval_type left_resid = right_subtract(key_value<Type>(first_), inter_val);
  397. if(!icl::is_empty(left_resid))
  398. { // [------------ . . .
  399. // [left_resid---first_ --- . . .
  400. iterator prior_ = cyclic_prior(object, first_);
  401. const_cast<interval_type&>(key_value<Type>(first_))
  402. = left_subtract(key_value<Type>(first_), left_resid);
  403. //NOTE: Only splitting
  404. object._insert(prior_, icl::make_value<Type>(left_resid, co_value<Type>(first_)));
  405. }
  406. //POST:
  407. // [----- inter_val ---- . . .
  408. // ...[-- first_ --...
  409. }
  410. template<class Type>
  411. void add_segment(Type& object, const typename Type::interval_type& inter_val,
  412. typename Type::iterator& it_ )
  413. {
  414. typedef typename Type::interval_type interval_type;
  415. interval_type lead_gap = right_subtract(inter_val, *it_);
  416. if(!icl::is_empty(lead_gap))
  417. // [lead_gap--- . . .
  418. // [prior_) [-- it_ ...
  419. object._insert(prior(it_), lead_gap);
  420. // . . . --------- . . . addend interval
  421. // [-- it_ --) has a common part with the first overval
  422. ++it_;
  423. }
  424. template<class Type>
  425. void add_main(Type& object, typename Type::interval_type& rest_interval,
  426. typename Type::iterator& it_,
  427. const typename Type::iterator& last_)
  428. {
  429. typedef typename Type::interval_type interval_type;
  430. interval_type cur_interval;
  431. while(it_ != last_)
  432. {
  433. cur_interval = *it_ ;
  434. add_segment(object, rest_interval, it_);
  435. // shrink interval
  436. rest_interval = left_subtract(rest_interval, cur_interval);
  437. }
  438. }
  439. template<class Type>
  440. void add_rear(Type& object, const typename Type::interval_type& inter_val,
  441. typename Type::iterator& it_ )
  442. {
  443. typedef typename Type::interval_type interval_type;
  444. typedef typename Type::iterator iterator;
  445. iterator prior_ = cyclic_prior(object, it_);
  446. interval_type cur_itv = *it_;
  447. interval_type lead_gap = right_subtract(inter_val, cur_itv);
  448. if(!icl::is_empty(lead_gap))
  449. // [lead_gap--- . . .
  450. // [prior_) [-- it_ ...
  451. object._insert(prior_, lead_gap);
  452. interval_type end_gap = left_subtract(inter_val, cur_itv);
  453. if(!icl::is_empty(end_gap))
  454. // [---------------end_gap)
  455. // [-- it_ --)
  456. it_ = object._insert(it_, end_gap);
  457. else
  458. {
  459. // only for the last there can be a right_resid: a part of *it_ right of addend
  460. interval_type right_resid = left_subtract(cur_itv, inter_val);
  461. if(!icl::is_empty(right_resid))
  462. {
  463. // [--------------)
  464. // [-- it_ --right_resid)
  465. const_cast<interval_type&>(*it_) = right_subtract(*it_, right_resid);
  466. it_ = object._insert(it_, right_resid);
  467. }
  468. }
  469. }
  470. //==============================================================================
  471. //= Addition
  472. //==============================================================================
  473. template<class Type>
  474. typename Type::iterator
  475. add(Type& object, const typename Type::value_type& addend)
  476. {
  477. //CL typedef typename Type::interval_type interval_type;
  478. typedef typename Type::iterator iterator;
  479. typedef typename on_style<Type, Type::fineness>::type on_style_;
  480. if(icl::is_empty(addend))
  481. return object.end();
  482. std::pair<iterator,bool> insertion = object._insert(addend);
  483. if(insertion.second)
  484. return on_style_::handle_inserted(object, insertion.first);
  485. else
  486. return on_style_::add_over(object, addend, insertion.first);
  487. }
  488. template<class Type>
  489. typename Type::iterator
  490. add(Type& object, typename Type::iterator prior_,
  491. const typename Type::value_type& addend)
  492. {
  493. //CL typedef typename Type::interval_type interval_type;
  494. typedef typename Type::iterator iterator;
  495. typedef typename on_style<Type, Type::fineness>::type on_style_;
  496. if(icl::is_empty(addend))
  497. return prior_;
  498. iterator insertion = object._insert(prior_, addend);
  499. if(*insertion == addend)
  500. return on_style_::handle_inserted(object, insertion);
  501. else
  502. return on_style_::add_over(object, addend);
  503. }
  504. //==============================================================================
  505. //= Subtraction
  506. //==============================================================================
  507. template<class Type>
  508. void subtract(Type& object, const typename Type::value_type& minuend)
  509. {
  510. typedef typename Type::iterator iterator;
  511. typedef typename Type::interval_type interval_type;
  512. //CL typedef typename Type::value_type value_type;
  513. if(icl::is_empty(minuend)) return;
  514. std::pair<iterator, iterator> exterior = object.equal_range(minuend);
  515. if(exterior.first == exterior.second) return;
  516. iterator first_ = exterior.first;
  517. iterator end_ = exterior.second;
  518. iterator last_ = end_; --last_;
  519. interval_type leftResid = right_subtract(*first_, minuend);
  520. interval_type rightResid;
  521. if(first_ != end_ )
  522. rightResid = left_subtract(*last_ , minuend);
  523. object.erase(first_, end_);
  524. if(!icl::is_empty(leftResid))
  525. object._insert(leftResid);
  526. if(!icl::is_empty(rightResid))
  527. object._insert(rightResid);
  528. }
  529. } // namespace Interval_Set
  530. }} // namespace icl boost
  531. #endif