interval_base_map.hpp 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390
  1. /*-----------------------------------------------------------------------------+
  2. Copyright (c) 2007-2012: Joachim Faulhaber
  3. Copyright (c) 1999-2006: Cortex Software GmbH, Kantstrasse 57, Berlin
  4. +------------------------------------------------------------------------------+
  5. Distributed under the Boost Software License, Version 1.0.
  6. (See accompanying file LICENCE.txt or copy at
  7. http://www.boost.org/LICENSE_1_0.txt)
  8. +-----------------------------------------------------------------------------*/
  9. #ifndef BOOST_ICL_INTERVAL_BASE_MAP_HPP_JOFA_990223
  10. #define BOOST_ICL_INTERVAL_BASE_MAP_HPP_JOFA_990223
  11. #include <limits>
  12. #include <boost/mpl/and.hpp>
  13. #include <boost/mpl/or.hpp>
  14. #include <boost/mpl/not.hpp>
  15. #include <boost/icl/detail/notate.hpp>
  16. #include <boost/icl/detail/design_config.hpp>
  17. #include <boost/icl/detail/on_absorbtion.hpp>
  18. #include <boost/icl/detail/interval_map_algo.hpp>
  19. #include <boost/icl/detail/exclusive_less_than.hpp>
  20. #include <boost/icl/associative_interval_container.hpp>
  21. #include <boost/icl/type_traits/is_interval_splitter.hpp>
  22. #include <boost/icl/map.hpp>
  23. namespace boost{namespace icl
  24. {
  25. template<class DomainT, class CodomainT>
  26. struct mapping_pair
  27. {
  28. DomainT key;
  29. CodomainT data;
  30. mapping_pair():key(), data(){}
  31. mapping_pair(const DomainT& key_value, const CodomainT& data_value)
  32. :key(key_value), data(data_value){}
  33. mapping_pair(const std::pair<DomainT,CodomainT>& std_pair)
  34. :key(std_pair.first), data(std_pair.second){}
  35. };
  36. /** \brief Implements a map as a map of intervals (base class) */
  37. template
  38. <
  39. class SubType,
  40. typename DomainT,
  41. typename CodomainT,
  42. class Traits = icl::partial_absorber,
  43. ICL_COMPARE Compare = ICL_COMPARE_INSTANCE(ICL_COMPARE_DEFAULT, DomainT),
  44. ICL_COMBINE Combine = ICL_COMBINE_INSTANCE(icl::inplace_plus, CodomainT),
  45. ICL_SECTION Section = ICL_SECTION_INSTANCE(icl::inter_section, CodomainT),
  46. ICL_INTERVAL(ICL_COMPARE) Interval = ICL_INTERVAL_INSTANCE(ICL_INTERVAL_DEFAULT, DomainT, Compare),
  47. ICL_ALLOC Alloc = std::allocator
  48. >
  49. class interval_base_map
  50. {
  51. public:
  52. //==========================================================================
  53. //= Associated types
  54. //==========================================================================
  55. typedef interval_base_map<SubType,DomainT,CodomainT,
  56. Traits,Compare,Combine,Section,Interval,Alloc>
  57. type;
  58. /// The designated \e derived or \e sub_type of this base class
  59. typedef SubType sub_type;
  60. /// Auxilliary type for overloadresolution
  61. typedef type overloadable_type;
  62. /// Traits of an itl map
  63. typedef Traits traits;
  64. //--------------------------------------------------------------------------
  65. //- Associated types: Related types
  66. //--------------------------------------------------------------------------
  67. /// The atomized type representing the corresponding container of elements
  68. typedef typename icl::map<DomainT,CodomainT,
  69. Traits,Compare,Combine,Section,Alloc> atomized_type;
  70. //--------------------------------------------------------------------------
  71. //- Associated types: Data
  72. //--------------------------------------------------------------------------
  73. /// Domain type (type of the keys) of the map
  74. typedef DomainT domain_type;
  75. typedef typename boost::call_traits<DomainT>::param_type domain_param;
  76. /// Domain type (type of the keys) of the map
  77. typedef CodomainT codomain_type;
  78. /// Auxiliary type to help the compiler resolve ambiguities when using std::make_pair
  79. typedef mapping_pair<domain_type,codomain_type> domain_mapping_type;
  80. /// Conceptual is a map a set of elements of type \c element_type
  81. typedef domain_mapping_type element_type;
  82. /// The interval type of the map
  83. typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) interval_type;
  84. /// Auxiliary type for overload resolution
  85. typedef std::pair<interval_type,CodomainT> interval_mapping_type;
  86. /// Type of an interval containers segment, that is spanned by an interval
  87. typedef std::pair<interval_type,CodomainT> segment_type;
  88. //--------------------------------------------------------------------------
  89. //- Associated types: Size
  90. //--------------------------------------------------------------------------
  91. /// The difference type of an interval which is sometimes different form the domain_type
  92. typedef typename difference_type_of<domain_type>::type difference_type;
  93. /// The size type of an interval which is mostly std::size_t
  94. typedef typename size_type_of<domain_type>::type size_type;
  95. //--------------------------------------------------------------------------
  96. //- Associated types: Functors
  97. //--------------------------------------------------------------------------
  98. /// Comparison functor for domain values
  99. typedef ICL_COMPARE_DOMAIN(Compare,DomainT) domain_compare;
  100. typedef ICL_COMPARE_DOMAIN(Compare,segment_type) segment_compare;
  101. /// Combine functor for codomain value aggregation
  102. typedef ICL_COMBINE_CODOMAIN(Combine,CodomainT) codomain_combine;
  103. /// Inverse Combine functor for codomain value aggregation
  104. typedef typename inverse<codomain_combine>::type inverse_codomain_combine;
  105. /// Intersection functor for codomain values
  106. typedef typename mpl::if_
  107. <has_set_semantics<codomain_type>
  108. , ICL_SECTION_CODOMAIN(Section,CodomainT)
  109. , codomain_combine
  110. >::type codomain_intersect;
  111. /// Inverse Combine functor for codomain value intersection
  112. typedef typename inverse<codomain_intersect>::type inverse_codomain_intersect;
  113. /// Comparison functor for intervals which are keys as well
  114. typedef exclusive_less_than<interval_type> interval_compare;
  115. /// Comparison functor for keys
  116. typedef exclusive_less_than<interval_type> key_compare;
  117. //--------------------------------------------------------------------------
  118. //- Associated types: Implementation and stl related
  119. //--------------------------------------------------------------------------
  120. /// The allocator type of the set
  121. typedef Alloc<std::pair<const interval_type, codomain_type> >
  122. allocator_type;
  123. /// Container type for the implementation
  124. typedef ICL_IMPL_SPACE::map<interval_type,codomain_type,
  125. key_compare,allocator_type> ImplMapT;
  126. /// key type of the implementing container
  127. typedef typename ImplMapT::key_type key_type;
  128. /// value type of the implementing container
  129. typedef typename ImplMapT::value_type value_type;
  130. /// data type of the implementing container
  131. typedef typename ImplMapT::value_type::second_type data_type;
  132. /// pointer type
  133. typedef typename ImplMapT::pointer pointer;
  134. /// const pointer type
  135. typedef typename ImplMapT::const_pointer const_pointer;
  136. /// reference type
  137. typedef typename ImplMapT::reference reference;
  138. /// const reference type
  139. typedef typename ImplMapT::const_reference const_reference;
  140. /// iterator for iteration over intervals
  141. typedef typename ImplMapT::iterator iterator;
  142. /// const_iterator for iteration over intervals
  143. typedef typename ImplMapT::const_iterator const_iterator;
  144. /// iterator for reverse iteration over intervals
  145. typedef typename ImplMapT::reverse_iterator reverse_iterator;
  146. /// const_iterator for iteration over intervals
  147. typedef typename ImplMapT::const_reverse_iterator const_reverse_iterator;
  148. /// element iterator: Depreciated, see documentation.
  149. typedef boost::icl::element_iterator<iterator> element_iterator;
  150. /// const element iterator: Depreciated, see documentation.
  151. typedef boost::icl::element_iterator<const_iterator> element_const_iterator;
  152. /// element reverse iterator: Depreciated, see documentation.
  153. typedef boost::icl::element_iterator<reverse_iterator> element_reverse_iterator;
  154. /// element const reverse iterator: Depreciated, see documentation.
  155. typedef boost::icl::element_iterator<const_reverse_iterator> element_const_reverse_iterator;
  156. typedef typename on_absorbtion<type, codomain_combine,
  157. Traits::absorbs_identities>::type on_codomain_absorbtion;
  158. public:
  159. BOOST_STATIC_CONSTANT(bool,
  160. is_total_invertible = ( Traits::is_total
  161. && has_inverse<codomain_type>::value));
  162. BOOST_STATIC_CONSTANT(int, fineness = 0);
  163. public:
  164. //==========================================================================
  165. //= Construct, copy, destruct
  166. //==========================================================================
  167. /** Default constructor for the empty object */
  168. interval_base_map()
  169. {
  170. BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>));
  171. BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>));
  172. BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<CodomainT>));
  173. BOOST_CONCEPT_ASSERT((EqualComparableConcept<CodomainT>));
  174. }
  175. /** Copy constructor */
  176. interval_base_map(const interval_base_map& src): _map(src._map)
  177. {
  178. BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>));
  179. BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>));
  180. BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<CodomainT>));
  181. BOOST_CONCEPT_ASSERT((EqualComparableConcept<CodomainT>));
  182. }
  183. # ifndef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  184. //==========================================================================
  185. //= Move semantics
  186. //==========================================================================
  187. /** Move constructor */
  188. interval_base_map(interval_base_map&& src): _map(boost::move(src._map))
  189. {
  190. BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>));
  191. BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>));
  192. BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<CodomainT>));
  193. BOOST_CONCEPT_ASSERT((EqualComparableConcept<CodomainT>));
  194. }
  195. /** Move assignment operator */
  196. interval_base_map& operator = (interval_base_map src)
  197. { //call by value sice 'src' is a "sink value"
  198. this->_map = boost::move(src._map);
  199. return *this;
  200. }
  201. //==========================================================================
  202. # else
  203. /** Copy assignment operator */
  204. interval_base_map& operator = (const interval_base_map& src)
  205. {
  206. this->_map = src._map;
  207. return *this;
  208. }
  209. # endif // BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  210. /** swap the content of containers */
  211. void swap(interval_base_map& object) { _map.swap(object._map); }
  212. //==========================================================================
  213. //= Containedness
  214. //==========================================================================
  215. /** clear the map */
  216. void clear() { icl::clear(*that()); }
  217. /** is the map empty? */
  218. bool empty()const { return icl::is_empty(*that()); }
  219. //==========================================================================
  220. //= Size
  221. //==========================================================================
  222. /** An interval map's size is it's cardinality */
  223. size_type size()const
  224. {
  225. return icl::cardinality(*that());
  226. }
  227. /** Size of the iteration over this container */
  228. std::size_t iterative_size()const
  229. {
  230. return _map.size();
  231. }
  232. //==========================================================================
  233. //= Selection
  234. //==========================================================================
  235. /** Find the interval value pair, that contains \c key */
  236. const_iterator find(const domain_type& key_value)const
  237. {
  238. return icl::find(*this, key_value);
  239. }
  240. /** Find the first interval value pair, that collides with interval
  241. \c key_interval */
  242. const_iterator find(const interval_type& key_interval)const
  243. {
  244. return _map.find(key_interval);
  245. }
  246. /** Total select function. */
  247. codomain_type operator()(const domain_type& key_value)const
  248. {
  249. const_iterator it_ = icl::find(*this, key_value);
  250. return it_==end() ? identity_element<codomain_type>::value()
  251. : (*it_).second;
  252. }
  253. //==========================================================================
  254. //= Addition
  255. //==========================================================================
  256. /** Addition of a key value pair to the map */
  257. SubType& add(const element_type& key_value_pair)
  258. {
  259. return icl::add(*that(), key_value_pair);
  260. }
  261. /** Addition of an interval value pair to the map. */
  262. SubType& add(const segment_type& interval_value_pair)
  263. {
  264. this->template _add<codomain_combine>(interval_value_pair);
  265. return *that();
  266. }
  267. /** Addition of an interval value pair \c interval_value_pair to the map.
  268. Iterator \c prior_ is a hint to the position \c interval_value_pair can be
  269. inserted after. */
  270. iterator add(iterator prior_, const segment_type& interval_value_pair)
  271. {
  272. return this->template _add<codomain_combine>(prior_, interval_value_pair);
  273. }
  274. //==========================================================================
  275. //= Subtraction
  276. //==========================================================================
  277. /** Subtraction of a key value pair from the map */
  278. SubType& subtract(const element_type& key_value_pair)
  279. {
  280. return icl::subtract(*that(), key_value_pair);
  281. }
  282. /** Subtraction of an interval value pair from the map. */
  283. SubType& subtract(const segment_type& interval_value_pair)
  284. {
  285. on_invertible<type, is_total_invertible>
  286. ::subtract(*that(), interval_value_pair);
  287. return *that();
  288. }
  289. //==========================================================================
  290. //= Insertion
  291. //==========================================================================
  292. /** Insertion of a \c key_value_pair into the map. */
  293. SubType& insert(const element_type& key_value_pair)
  294. {
  295. return icl::insert(*that(), key_value_pair);
  296. }
  297. /** Insertion of an \c interval_value_pair into the map. */
  298. SubType& insert(const segment_type& interval_value_pair)
  299. {
  300. _insert(interval_value_pair);
  301. return *that();
  302. }
  303. /** Insertion of an \c interval_value_pair into the map. Iterator \c prior_.
  304. serves as a hint to insert after the element \c prior point to. */
  305. iterator insert(iterator prior, const segment_type& interval_value_pair)
  306. {
  307. return _insert(prior, interval_value_pair);
  308. }
  309. /** With <tt>key_value_pair = (k,v)</tt> set value \c v for key \c k */
  310. SubType& set(const element_type& key_value_pair)
  311. {
  312. return icl::set_at(*that(), key_value_pair);
  313. }
  314. /** With <tt>interval_value_pair = (I,v)</tt> set value \c v
  315. for all keys in interval \c I in the map. */
  316. SubType& set(const segment_type& interval_value_pair)
  317. {
  318. return icl::set_at(*that(), interval_value_pair);
  319. }
  320. //==========================================================================
  321. //= Erasure
  322. //==========================================================================
  323. /** Erase a \c key_value_pair from the map. */
  324. SubType& erase(const element_type& key_value_pair)
  325. {
  326. icl::erase(*that(), key_value_pair);
  327. return *that();
  328. }
  329. /** Erase an \c interval_value_pair from the map. */
  330. SubType& erase(const segment_type& interval_value_pair);
  331. /** Erase a key value pair for \c key. */
  332. SubType& erase(const domain_type& key)
  333. {
  334. return icl::erase(*that(), key);
  335. }
  336. /** Erase all value pairs within the range of the
  337. interval <tt>inter_val</tt> from the map. */
  338. SubType& erase(const interval_type& inter_val);
  339. /** Erase all value pairs within the range of the interval that iterator
  340. \c position points to. */
  341. void erase(iterator position){ this->_map.erase(position); }
  342. /** Erase all value pairs for a range of iterators <tt>[first,past)</tt>. */
  343. void erase(iterator first, iterator past){ this->_map.erase(first, past); }
  344. //==========================================================================
  345. //= Intersection
  346. //==========================================================================
  347. /** The intersection of \c interval_value_pair and \c *this map is added to \c section. */
  348. void add_intersection(SubType& section, const segment_type& interval_value_pair)const
  349. {
  350. on_definedness<SubType, Traits::is_total>
  351. ::add_intersection(section, *that(), interval_value_pair);
  352. }
  353. //==========================================================================
  354. //= Symmetric difference
  355. //==========================================================================
  356. /** If \c *this map contains \c key_value_pair it is erased, otherwise it is added. */
  357. SubType& flip(const element_type& key_value_pair)
  358. {
  359. return icl::flip(*that(), key_value_pair);
  360. }
  361. /** If \c *this map contains \c interval_value_pair it is erased, otherwise it is added. */
  362. SubType& flip(const segment_type& interval_value_pair)
  363. {
  364. on_total_absorbable<SubType, Traits::is_total, Traits::absorbs_identities>
  365. ::flip(*that(), interval_value_pair);
  366. return *that();
  367. }
  368. //==========================================================================
  369. //= Iterator related
  370. //==========================================================================
  371. iterator lower_bound(const key_type& interval)
  372. { return _map.lower_bound(interval); }
  373. iterator upper_bound(const key_type& interval)
  374. { return _map.upper_bound(interval); }
  375. const_iterator lower_bound(const key_type& interval)const
  376. { return _map.lower_bound(interval); }
  377. const_iterator upper_bound(const key_type& interval)const
  378. { return _map.upper_bound(interval); }
  379. std::pair<iterator,iterator> equal_range(const key_type& interval)
  380. {
  381. return std::pair<iterator,iterator>
  382. (lower_bound(interval), upper_bound(interval));
  383. }
  384. std::pair<const_iterator,const_iterator>
  385. equal_range(const key_type& interval)const
  386. {
  387. return std::pair<const_iterator,const_iterator>
  388. (lower_bound(interval), upper_bound(interval));
  389. }
  390. iterator begin() { return _map.begin(); }
  391. iterator end() { return _map.end(); }
  392. const_iterator begin()const { return _map.begin(); }
  393. const_iterator end()const { return _map.end(); }
  394. reverse_iterator rbegin() { return _map.rbegin(); }
  395. reverse_iterator rend() { return _map.rend(); }
  396. const_reverse_iterator rbegin()const { return _map.rbegin(); }
  397. const_reverse_iterator rend()const { return _map.rend(); }
  398. private:
  399. template<class Combiner>
  400. iterator _add(const segment_type& interval_value_pair);
  401. template<class Combiner>
  402. iterator _add(iterator prior_, const segment_type& interval_value_pair);
  403. template<class Combiner>
  404. void _subtract(const segment_type& interval_value_pair);
  405. iterator _insert(const segment_type& interval_value_pair);
  406. iterator _insert(iterator prior_, const segment_type& interval_value_pair);
  407. private:
  408. template<class Combiner>
  409. void add_segment(const interval_type& inter_val, const CodomainT& co_val, iterator& it_);
  410. template<class Combiner>
  411. void add_main(interval_type& inter_val, const CodomainT& co_val,
  412. iterator& it_, const iterator& last_);
  413. template<class Combiner>
  414. void add_rear(const interval_type& inter_val, const CodomainT& co_val, iterator& it_);
  415. void add_front(const interval_type& inter_val, iterator& first_);
  416. private:
  417. void subtract_front(const interval_type& inter_val, iterator& first_);
  418. template<class Combiner>
  419. void subtract_main(const CodomainT& co_val, iterator& it_, const iterator& last_);
  420. template<class Combiner>
  421. void subtract_rear(interval_type& inter_val, const CodomainT& co_val, iterator& it_);
  422. private:
  423. void insert_main(const interval_type&, const CodomainT&, iterator&, const iterator&);
  424. void erase_rest ( interval_type&, const CodomainT&, iterator&, const iterator&);
  425. template<class FragmentT>
  426. void total_add_intersection(SubType& section, const FragmentT& fragment)const
  427. {
  428. section += *that();
  429. section.add(fragment);
  430. }
  431. void partial_add_intersection(SubType& section, const segment_type& operand)const
  432. {
  433. interval_type inter_val = operand.first;
  434. if(icl::is_empty(inter_val))
  435. return;
  436. std::pair<const_iterator, const_iterator> exterior = equal_range(inter_val);
  437. if(exterior.first == exterior.second)
  438. return;
  439. for(const_iterator it_=exterior.first; it_ != exterior.second; it_++)
  440. {
  441. interval_type common_interval = (*it_).first & inter_val;
  442. if(!icl::is_empty(common_interval))
  443. {
  444. section.template _add<codomain_combine> (value_type(common_interval, (*it_).second) );
  445. section.template _add<codomain_intersect>(value_type(common_interval, operand.second));
  446. }
  447. }
  448. }
  449. void partial_add_intersection(SubType& section, const element_type& operand)const
  450. {
  451. partial_add_intersection(section, make_segment<type>(operand));
  452. }
  453. protected:
  454. template <class Combiner>
  455. iterator gap_insert(iterator prior_, const interval_type& inter_val,
  456. const codomain_type& co_val )
  457. {
  458. // inter_val is not conained in this map. Insertion will be successful
  459. BOOST_ASSERT(this->_map.find(inter_val) == this->_map.end());
  460. BOOST_ASSERT((!on_absorbtion<type,Combiner,Traits::absorbs_identities>::is_absorbable(co_val)));
  461. return this->_map.insert(prior_, value_type(inter_val, version<Combiner>()(co_val)));
  462. }
  463. template <class Combiner>
  464. std::pair<iterator, bool>
  465. add_at(const iterator& prior_, const interval_type& inter_val,
  466. const codomain_type& co_val )
  467. {
  468. // Never try to insert an identity element into an identity element absorber here:
  469. BOOST_ASSERT((!(on_absorbtion<type,Combiner,Traits::absorbs_identities>::is_absorbable(co_val))));
  470. iterator inserted_
  471. = this->_map.insert(prior_, value_type(inter_val, Combiner::identity_element()));
  472. if((*inserted_).first == inter_val && (*inserted_).second == Combiner::identity_element())
  473. {
  474. Combiner()((*inserted_).second, co_val);
  475. return std::pair<iterator,bool>(inserted_, true);
  476. }
  477. else
  478. return std::pair<iterator,bool>(inserted_, false);
  479. }
  480. std::pair<iterator, bool>
  481. insert_at(const iterator& prior_, const interval_type& inter_val,
  482. const codomain_type& co_val )
  483. {
  484. iterator inserted_
  485. = this->_map.insert(prior_, value_type(inter_val, co_val));
  486. if(inserted_ == prior_)
  487. return std::pair<iterator,bool>(inserted_, false);
  488. else if((*inserted_).first == inter_val)
  489. return std::pair<iterator,bool>(inserted_, true);
  490. else
  491. return std::pair<iterator,bool>(inserted_, false);
  492. }
  493. protected:
  494. sub_type* that() { return static_cast<sub_type*>(this); }
  495. const sub_type* that()const { return static_cast<const sub_type*>(this); }
  496. protected:
  497. ImplMapT _map;
  498. private:
  499. //--------------------------------------------------------------------------
  500. template<class Type, bool is_total_invertible>
  501. struct on_invertible;
  502. template<class Type>
  503. struct on_invertible<Type, true>
  504. {
  505. typedef typename Type::segment_type segment_type;
  506. typedef typename Type::inverse_codomain_combine inverse_codomain_combine;
  507. static void subtract(Type& object, const segment_type& operand)
  508. { object.template _add<inverse_codomain_combine>(operand); }
  509. };
  510. template<class Type>
  511. struct on_invertible<Type, false>
  512. {
  513. typedef typename Type::segment_type segment_type;
  514. typedef typename Type::inverse_codomain_combine inverse_codomain_combine;
  515. static void subtract(Type& object, const segment_type& operand)
  516. { object.template _subtract<inverse_codomain_combine>(operand); }
  517. };
  518. friend struct on_invertible<type, true>;
  519. friend struct on_invertible<type, false>;
  520. //--------------------------------------------------------------------------
  521. //--------------------------------------------------------------------------
  522. template<class Type, bool is_total>
  523. struct on_definedness;
  524. template<class Type>
  525. struct on_definedness<Type, true>
  526. {
  527. static void add_intersection(Type& section, const Type& object,
  528. const segment_type& operand)
  529. { object.total_add_intersection(section, operand); }
  530. };
  531. template<class Type>
  532. struct on_definedness<Type, false>
  533. {
  534. static void add_intersection(Type& section, const Type& object,
  535. const segment_type& operand)
  536. { object.partial_add_intersection(section, operand); }
  537. };
  538. friend struct on_definedness<type, true>;
  539. friend struct on_definedness<type, false>;
  540. //--------------------------------------------------------------------------
  541. //--------------------------------------------------------------------------
  542. template<class Type, bool has_set_semantics>
  543. struct on_codomain_model;
  544. template<class Type>
  545. struct on_codomain_model<Type, true>
  546. {
  547. typedef typename Type::interval_type interval_type;
  548. typedef typename Type::codomain_type codomain_type;
  549. typedef typename Type::segment_type segment_type;
  550. typedef typename Type::codomain_combine codomain_combine;
  551. typedef typename Type::inverse_codomain_intersect inverse_codomain_intersect;
  552. static void add(Type& intersection, interval_type& common_interval,
  553. const codomain_type& flip_value, const codomain_type& co_value)
  554. {
  555. codomain_type common_value = flip_value;
  556. inverse_codomain_intersect()(common_value, co_value);
  557. intersection.template
  558. _add<codomain_combine>(segment_type(common_interval, common_value));
  559. }
  560. };
  561. template<class Type>
  562. struct on_codomain_model<Type, false>
  563. {
  564. typedef typename Type::interval_type interval_type;
  565. typedef typename Type::codomain_type codomain_type;
  566. typedef typename Type::segment_type segment_type;
  567. typedef typename Type::codomain_combine codomain_combine;
  568. static void add(Type& intersection, interval_type& common_interval,
  569. const codomain_type&, const codomain_type&)
  570. {
  571. intersection.template
  572. _add<codomain_combine>(segment_type(common_interval,
  573. identity_element<codomain_type>::value()));
  574. }
  575. };
  576. friend struct on_codomain_model<type, true>;
  577. friend struct on_codomain_model<type, false>;
  578. //--------------------------------------------------------------------------
  579. //--------------------------------------------------------------------------
  580. template<class Type, bool is_total, bool absorbs_identities>
  581. struct on_total_absorbable;
  582. template<class Type>
  583. struct on_total_absorbable<Type, true, true>
  584. {
  585. static void flip(Type& object, const typename Type::segment_type&)
  586. { icl::clear(object); }
  587. };
  588. #ifdef BOOST_MSVC
  589. #pragma warning(push)
  590. #pragma warning(disable:4127) // conditional expression is constant
  591. #endif
  592. template<class Type>
  593. struct on_total_absorbable<Type, true, false>
  594. {
  595. typedef typename Type::segment_type segment_type;
  596. typedef typename Type::codomain_type codomain_type;
  597. static void flip(Type& object, const segment_type& operand)
  598. {
  599. object += operand;
  600. ICL_FORALL(typename Type, it_, object)
  601. (*it_).second = identity_element<codomain_type>::value();
  602. if(mpl::not_<is_interval_splitter<Type> >::value)
  603. icl::join(object);
  604. }
  605. };
  606. #ifdef BOOST_MSVC
  607. #pragma warning(pop)
  608. #endif
  609. template<class Type, bool absorbs_identities>
  610. struct on_total_absorbable<Type, false, absorbs_identities>
  611. {
  612. typedef typename Type::segment_type segment_type;
  613. typedef typename Type::codomain_type codomain_type;
  614. typedef typename Type::interval_type interval_type;
  615. typedef typename Type::value_type value_type;
  616. typedef typename Type::const_iterator const_iterator;
  617. typedef typename Type::set_type set_type;
  618. typedef typename Type::inverse_codomain_intersect inverse_codomain_intersect;
  619. static void flip(Type& object, const segment_type& interval_value_pair)
  620. {
  621. // That which is common shall be subtracted
  622. // That which is not shall be added
  623. // So interval_value_pair has to be 'complementary added' or flipped
  624. interval_type span = interval_value_pair.first;
  625. std::pair<const_iterator, const_iterator> exterior
  626. = object.equal_range(span);
  627. const_iterator first_ = exterior.first;
  628. const_iterator end_ = exterior.second;
  629. interval_type covered, left_over, common_interval;
  630. const codomain_type& x_value = interval_value_pair.second;
  631. const_iterator it_ = first_;
  632. set_type eraser;
  633. Type intersection;
  634. while(it_ != end_ )
  635. {
  636. const codomain_type& co_value = (*it_).second;
  637. covered = (*it_++).first;
  638. //[a ... : span
  639. // [b ... : covered
  640. //[a b) : left_over
  641. left_over = right_subtract(span, covered);
  642. //That which is common ...
  643. common_interval = span & covered;
  644. if(!icl::is_empty(common_interval))
  645. {
  646. // ... shall be subtracted
  647. icl::add(eraser, common_interval);
  648. on_codomain_model<Type, has_set_semantics<codomain_type>::value>
  649. ::add(intersection, common_interval, x_value, co_value);
  650. }
  651. icl::add(object, value_type(left_over, x_value)); //That which is not shall be added
  652. // Because this is a collision free addition I don't have to distinguish codomain_types.
  653. //... d) : span
  654. //... c) : covered
  655. // [c d) : span'
  656. span = left_subtract(span, covered);
  657. }
  658. //If span is not empty here, it is not in the set so it shall be added
  659. icl::add(object, value_type(span, x_value));
  660. //finally rewrite the common segments
  661. icl::erase(object, eraser);
  662. object += intersection;
  663. }
  664. };
  665. //--------------------------------------------------------------------------
  666. } ;
  667. //==============================================================================
  668. //= Addition detail
  669. //==============================================================================
  670. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  671. inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  672. ::add_front(const interval_type& inter_val, iterator& first_)
  673. {
  674. // If the collision sequence has a left residual 'left_resid' it will
  675. // be split, to provide a standardized start of algorithms:
  676. // The addend interval 'inter_val' covers the beginning of the collision sequence.
  677. // only for the first there can be a left_resid: a part of *first_ left of inter_val
  678. interval_type left_resid = right_subtract((*first_).first, inter_val);
  679. if(!icl::is_empty(left_resid))
  680. { // [------------ . . .
  681. // [left_resid---first_ --- . . .
  682. iterator prior_ = cyclic_prior(*this, first_);
  683. const_cast<interval_type&>((*first_).first)
  684. = left_subtract((*first_).first, left_resid);
  685. //NOTE: Only splitting
  686. this->_map.insert(prior_, segment_type(left_resid, (*first_).second));
  687. }
  688. //POST:
  689. // [----- inter_val ---- . . .
  690. // ...[-- first_ --...
  691. }
  692. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  693. template<class Combiner>
  694. inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  695. ::add_segment(const interval_type& inter_val, const CodomainT& co_val, iterator& it_)
  696. {
  697. interval_type lead_gap = right_subtract(inter_val, (*it_).first);
  698. if(!icl::is_empty(lead_gap))
  699. {
  700. // [lead_gap--- . . .
  701. // [-- it_ ...
  702. iterator prior_ = it_==this->_map.begin()? it_ : prior(it_);
  703. iterator inserted_ = this->template gap_insert<Combiner>(prior_, lead_gap, co_val);
  704. that()->handle_inserted(prior_, inserted_);
  705. }
  706. // . . . --------- . . . addend interval
  707. // [-- it_ --) has a common part with the first overval
  708. Combiner()((*it_).second, co_val);
  709. that()->template handle_left_combined<Combiner>(it_++);
  710. }
  711. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  712. template<class Combiner>
  713. inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  714. ::add_main(interval_type& inter_val, const CodomainT& co_val,
  715. iterator& it_, const iterator& last_)
  716. {
  717. interval_type cur_interval;
  718. while(it_!=last_)
  719. {
  720. cur_interval = (*it_).first ;
  721. add_segment<Combiner>(inter_val, co_val, it_);
  722. // shrink interval
  723. inter_val = left_subtract(inter_val, cur_interval);
  724. }
  725. }
  726. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  727. template<class Combiner>
  728. inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  729. ::add_rear(const interval_type& inter_val, const CodomainT& co_val, iterator& it_)
  730. {
  731. iterator prior_ = cyclic_prior(*that(), it_);
  732. interval_type cur_itv = (*it_).first ;
  733. interval_type lead_gap = right_subtract(inter_val, cur_itv);
  734. if(!icl::is_empty(lead_gap))
  735. { // [lead_gap--- . . .
  736. // [prior) [-- it_ ...
  737. iterator inserted_ = this->template gap_insert<Combiner>(prior_, lead_gap, co_val);
  738. that()->handle_inserted(prior_, inserted_);
  739. }
  740. interval_type end_gap = left_subtract(inter_val, cur_itv);
  741. if(!icl::is_empty(end_gap))
  742. {
  743. // [----------------end_gap)
  744. // . . . -- it_ --)
  745. Combiner()((*it_).second, co_val);
  746. that()->template gap_insert_at<Combiner>(it_, prior_, end_gap, co_val);
  747. }
  748. else
  749. {
  750. // only for the last there can be a right_resid: a part of *it_ right of x
  751. interval_type right_resid = left_subtract(cur_itv, inter_val);
  752. if(icl::is_empty(right_resid))
  753. {
  754. // [---------------)
  755. // [-- it_ ---)
  756. Combiner()((*it_).second, co_val);
  757. that()->template handle_preceeded_combined<Combiner>(prior_, it_);
  758. }
  759. else
  760. {
  761. // [--------------)
  762. // [-- it_ --right_resid)
  763. const_cast<interval_type&>((*it_).first) = right_subtract((*it_).first, right_resid);
  764. //NOTE: This is NOT an insertion that has to take care for correct application of
  765. // the Combiner functor. It only reestablished that state after splitting the
  766. // 'it_' interval value pair. Using _map_insert<Combiner> does not work here.
  767. iterator insertion_ = this->_map.insert(it_, value_type(right_resid, (*it_).second));
  768. that()->handle_reinserted(insertion_);
  769. Combiner()((*it_).second, co_val);
  770. that()->template handle_preceeded_combined<Combiner>(insertion_, it_);
  771. }
  772. }
  773. }
  774. //==============================================================================
  775. //= Addition
  776. //==============================================================================
  777. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  778. template<class Combiner>
  779. inline typename interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>::iterator
  780. interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  781. ::_add(const segment_type& addend)
  782. {
  783. typedef typename on_absorbtion<type,Combiner,
  784. absorbs_identities<type>::value>::type on_absorbtion_;
  785. const interval_type& inter_val = addend.first;
  786. if(icl::is_empty(inter_val))
  787. return this->_map.end();
  788. const codomain_type& co_val = addend.second;
  789. if(on_absorbtion_::is_absorbable(co_val))
  790. return this->_map.end();
  791. std::pair<iterator,bool> insertion
  792. = this->_map.insert(value_type(inter_val, version<Combiner>()(co_val)));
  793. if(insertion.second)
  794. return that()->handle_inserted(insertion.first);
  795. else
  796. {
  797. // Detect the first and the end iterator of the collision sequence
  798. iterator first_ = this->_map.lower_bound(inter_val),
  799. last_ = prior(this->_map.upper_bound(inter_val));
  800. //assert(end_ == this->_map.upper_bound(inter_val));
  801. iterator it_ = first_;
  802. interval_type rest_interval = inter_val;
  803. add_front (rest_interval, it_ );
  804. add_main<Combiner>(rest_interval, co_val, it_, last_);
  805. add_rear<Combiner>(rest_interval, co_val, it_ );
  806. return it_;
  807. }
  808. }
  809. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  810. template<class Combiner>
  811. inline typename interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>::iterator
  812. interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  813. ::_add(iterator prior_, const segment_type& addend)
  814. {
  815. typedef typename on_absorbtion<type,Combiner,
  816. absorbs_identities<type>::value>::type on_absorbtion_;
  817. const interval_type& inter_val = addend.first;
  818. if(icl::is_empty(inter_val))
  819. return prior_;
  820. const codomain_type& co_val = addend.second;
  821. if(on_absorbtion_::is_absorbable(co_val))
  822. return prior_;
  823. std::pair<iterator,bool> insertion
  824. = add_at<Combiner>(prior_, inter_val, co_val);
  825. if(insertion.second)
  826. return that()->handle_inserted(insertion.first);
  827. else
  828. {
  829. // Detect the first and the end iterator of the collision sequence
  830. std::pair<iterator,iterator> overlap = equal_range(inter_val);
  831. iterator it_ = overlap.first,
  832. last_ = prior(overlap.second);
  833. interval_type rest_interval = inter_val;
  834. add_front (rest_interval, it_ );
  835. add_main<Combiner>(rest_interval, co_val, it_, last_);
  836. add_rear<Combiner>(rest_interval, co_val, it_ );
  837. return it_;
  838. }
  839. }
  840. //==============================================================================
  841. //= Subtraction detail
  842. //==============================================================================
  843. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  844. inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  845. ::subtract_front(const interval_type& inter_val, iterator& it_)
  846. {
  847. interval_type left_resid = right_subtract((*it_).first, inter_val);
  848. if(!icl::is_empty(left_resid)) // [--- inter_val ---)
  849. { //[prior_) [left_resid)[--- it_ . . .
  850. iterator prior_ = cyclic_prior(*this, it_);
  851. const_cast<interval_type&>((*it_).first) = left_subtract((*it_).first, left_resid);
  852. this->_map.insert(prior_, value_type(left_resid, (*it_).second));
  853. // The segemnt *it_ is split at inter_val.first(), so as an invariant
  854. // segment *it_ is always "under" inter_val and a left_resid is empty.
  855. }
  856. }
  857. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  858. template<class Combiner>
  859. inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  860. ::subtract_main(const CodomainT& co_val, iterator& it_, const iterator& last_)
  861. {
  862. while(it_ != last_)
  863. {
  864. Combiner()((*it_).second, co_val);
  865. that()->template handle_left_combined<Combiner>(it_++);
  866. }
  867. }
  868. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  869. template<class Combiner>
  870. inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  871. ::subtract_rear(interval_type& inter_val, const CodomainT& co_val, iterator& it_)
  872. {
  873. interval_type right_resid = left_subtract((*it_).first, inter_val);
  874. if(icl::is_empty(right_resid))
  875. {
  876. Combiner()((*it_).second, co_val);
  877. that()->template handle_combined<Combiner>(it_);
  878. }
  879. else
  880. {
  881. const_cast<interval_type&>((*it_).first) = right_subtract((*it_).first, right_resid);
  882. iterator next_ = this->_map.insert(it_, value_type(right_resid, (*it_).second));
  883. Combiner()((*it_).second, co_val);
  884. that()->template handle_succeeded_combined<Combiner>(it_, next_);
  885. }
  886. }
  887. //==============================================================================
  888. //= Subtraction
  889. //==============================================================================
  890. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  891. template<class Combiner>
  892. inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  893. ::_subtract(const segment_type& minuend)
  894. {
  895. interval_type inter_val = minuend.first;
  896. if(icl::is_empty(inter_val))
  897. return;
  898. const codomain_type& co_val = minuend.second;
  899. if(on_absorbtion<type,Combiner,Traits::absorbs_identities>::is_absorbable(co_val))
  900. return;
  901. std::pair<iterator, iterator> exterior = equal_range(inter_val);
  902. if(exterior.first == exterior.second)
  903. return;
  904. iterator last_ = prior(exterior.second);
  905. iterator it_ = exterior.first;
  906. subtract_front (inter_val, it_ );
  907. subtract_main <Combiner>( co_val, it_, last_);
  908. subtract_rear <Combiner>(inter_val, co_val, it_ );
  909. }
  910. //==============================================================================
  911. //= Insertion
  912. //==============================================================================
  913. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  914. inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  915. ::insert_main(const interval_type& inter_val, const CodomainT& co_val,
  916. iterator& it_, const iterator& last_)
  917. {
  918. iterator end_ = boost::next(last_);
  919. iterator prior_ = cyclic_prior(*this,it_), inserted_;
  920. interval_type rest_interval = inter_val, left_gap, cur_itv;
  921. interval_type last_interval = last_ ->first;
  922. while(it_ != end_ )
  923. {
  924. cur_itv = (*it_).first ;
  925. left_gap = right_subtract(rest_interval, cur_itv);
  926. if(!icl::is_empty(left_gap))
  927. {
  928. inserted_ = this->_map.insert(prior_, value_type(left_gap, co_val));
  929. it_ = that()->handle_inserted(inserted_);
  930. }
  931. // shrink interval
  932. rest_interval = left_subtract(rest_interval, cur_itv);
  933. prior_ = it_;
  934. ++it_;
  935. }
  936. //insert_rear(rest_interval, co_val, last_):
  937. interval_type end_gap = left_subtract(rest_interval, last_interval);
  938. if(!icl::is_empty(end_gap))
  939. {
  940. inserted_ = this->_map.insert(prior_, value_type(end_gap, co_val));
  941. it_ = that()->handle_inserted(inserted_);
  942. }
  943. else
  944. it_ = prior_;
  945. }
  946. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  947. inline typename interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>::iterator
  948. interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  949. ::_insert(const segment_type& addend)
  950. {
  951. interval_type inter_val = addend.first;
  952. if(icl::is_empty(inter_val))
  953. return this->_map.end();
  954. const codomain_type& co_val = addend.second;
  955. if(on_codomain_absorbtion::is_absorbable(co_val))
  956. return this->_map.end();
  957. std::pair<iterator,bool> insertion = this->_map.insert(addend);
  958. if(insertion.second)
  959. return that()->handle_inserted(insertion.first);
  960. else
  961. {
  962. // Detect the first and the end iterator of the collision sequence
  963. iterator first_ = this->_map.lower_bound(inter_val),
  964. last_ = prior(this->_map.upper_bound(inter_val));
  965. //assert((++last_) == this->_map.upper_bound(inter_val));
  966. iterator it_ = first_;
  967. insert_main(inter_val, co_val, it_, last_);
  968. return it_;
  969. }
  970. }
  971. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  972. inline typename interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>::iterator
  973. interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  974. ::_insert(iterator prior_, const segment_type& addend)
  975. {
  976. interval_type inter_val = addend.first;
  977. if(icl::is_empty(inter_val))
  978. return prior_;
  979. const codomain_type& co_val = addend.second;
  980. if(on_codomain_absorbtion::is_absorbable(co_val))
  981. return prior_;
  982. std::pair<iterator,bool> insertion = insert_at(prior_, inter_val, co_val);
  983. if(insertion.second)
  984. return that()->handle_inserted(insertion.first);
  985. {
  986. // Detect the first and the end iterator of the collision sequence
  987. std::pair<iterator,iterator> overlap = equal_range(inter_val);
  988. iterator it_ = overlap.first,
  989. last_ = prior(overlap.second);
  990. insert_main(inter_val, co_val, it_, last_);
  991. return it_;
  992. }
  993. }
  994. //==============================================================================
  995. //= Erasure segment_type
  996. //==============================================================================
  997. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  998. inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  999. ::erase_rest(interval_type& inter_val, const CodomainT& co_val,
  1000. iterator& it_, const iterator& last_)
  1001. {
  1002. // For all intervals within loop: (*it_).first are contained_in inter_val
  1003. while(it_ != last_)
  1004. if((*it_).second == co_val)
  1005. this->_map.erase(it_++);
  1006. else it_++;
  1007. //erase_rear:
  1008. if((*it_).second == co_val)
  1009. {
  1010. interval_type right_resid = left_subtract((*it_).first, inter_val);
  1011. if(icl::is_empty(right_resid))
  1012. this->_map.erase(it_);
  1013. else
  1014. const_cast<interval_type&>((*it_).first) = right_resid;
  1015. }
  1016. }
  1017. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  1018. inline SubType& interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  1019. ::erase(const segment_type& minuend)
  1020. {
  1021. interval_type inter_val = minuend.first;
  1022. if(icl::is_empty(inter_val))
  1023. return *that();
  1024. const codomain_type& co_val = minuend.second;
  1025. if(on_codomain_absorbtion::is_absorbable(co_val))
  1026. return *that();
  1027. std::pair<iterator,iterator> exterior = equal_range(inter_val);
  1028. if(exterior.first == exterior.second)
  1029. return *that();
  1030. iterator first_ = exterior.first, end_ = exterior.second,
  1031. last_ = cyclic_prior(*this, end_);
  1032. iterator second_= first_; ++second_;
  1033. if(first_ == last_)
  1034. { // [----inter_val----)
  1035. // .....first_==last_.....
  1036. // only for the last there can be a right_resid: a part of *it_ right of minuend
  1037. interval_type right_resid = left_subtract((*first_).first, inter_val);
  1038. if((*first_).second == co_val)
  1039. {
  1040. interval_type left_resid = right_subtract((*first_).first, inter_val);
  1041. if(!icl::is_empty(left_resid)) // [----inter_val----)
  1042. { // [left_resid)..first_==last_......
  1043. const_cast<interval_type&>((*first_).first) = left_resid;
  1044. if(!icl::is_empty(right_resid))
  1045. this->_map.insert(first_, value_type(right_resid, co_val));
  1046. }
  1047. else if(!icl::is_empty(right_resid))
  1048. const_cast<interval_type&>((*first_).first) = right_resid;
  1049. else
  1050. this->_map.erase(first_);
  1051. }
  1052. }
  1053. else
  1054. {
  1055. // first AND NOT last
  1056. if((*first_).second == co_val)
  1057. {
  1058. interval_type left_resid = right_subtract((*first_).first, inter_val);
  1059. if(icl::is_empty(left_resid))
  1060. this->_map.erase(first_);
  1061. else
  1062. const_cast<interval_type&>((*first_).first) = left_resid;
  1063. }
  1064. erase_rest(inter_val, co_val, second_, last_);
  1065. }
  1066. return *that();
  1067. }
  1068. //==============================================================================
  1069. //= Erasure key_type
  1070. //==============================================================================
  1071. template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
  1072. inline SubType& interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
  1073. ::erase(const interval_type& minuend)
  1074. {
  1075. if(icl::is_empty(minuend))
  1076. return *that();
  1077. std::pair<iterator, iterator> exterior = equal_range(minuend);
  1078. if(exterior.first == exterior.second)
  1079. return *that();
  1080. iterator first_ = exterior.first,
  1081. end_ = exterior.second,
  1082. last_ = prior(end_);
  1083. interval_type left_resid = right_subtract((*first_).first, minuend);
  1084. interval_type right_resid = left_subtract(last_ ->first, minuend);
  1085. if(first_ == last_ )
  1086. if(!icl::is_empty(left_resid))
  1087. {
  1088. const_cast<interval_type&>((*first_).first) = left_resid;
  1089. if(!icl::is_empty(right_resid))
  1090. this->_map.insert(first_, value_type(right_resid, (*first_).second));
  1091. }
  1092. else if(!icl::is_empty(right_resid))
  1093. const_cast<interval_type&>((*first_).first) = left_subtract((*first_).first, minuend);
  1094. else
  1095. this->_map.erase(first_);
  1096. else
  1097. { // [-------- minuend ---------)
  1098. // [left_resid fst) . . . . [lst right_resid)
  1099. iterator second_= first_; ++second_;
  1100. iterator start_ = icl::is_empty(left_resid)? first_: second_;
  1101. iterator stop_ = icl::is_empty(right_resid)? end_ : last_ ;
  1102. this->_map.erase(start_, stop_); //erase [start_, stop_)
  1103. if(!icl::is_empty(left_resid))
  1104. const_cast<interval_type&>((*first_).first) = left_resid;
  1105. if(!icl::is_empty(right_resid))
  1106. const_cast<interval_type&>(last_ ->first) = right_resid;
  1107. }
  1108. return *that();
  1109. }
  1110. //-----------------------------------------------------------------------------
  1111. // type traits
  1112. //-----------------------------------------------------------------------------
  1113. template
  1114. <
  1115. class SubType,
  1116. class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc
  1117. >
  1118. struct is_map<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> >
  1119. {
  1120. typedef is_map<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> > type;
  1121. BOOST_STATIC_CONSTANT(bool, value = true);
  1122. };
  1123. template
  1124. <
  1125. class SubType,
  1126. class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc
  1127. >
  1128. struct has_inverse<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> >
  1129. {
  1130. typedef has_inverse<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> > type;
  1131. BOOST_STATIC_CONSTANT(bool, value = (has_inverse<CodomainT>::value));
  1132. };
  1133. template
  1134. <
  1135. class SubType,
  1136. class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc
  1137. >
  1138. struct is_interval_container<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> >
  1139. {
  1140. typedef is_interval_container<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> > type;
  1141. BOOST_STATIC_CONSTANT(bool, value = true);
  1142. };
  1143. template
  1144. <
  1145. class SubType,
  1146. class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc
  1147. >
  1148. struct absorbs_identities<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> >
  1149. {
  1150. typedef absorbs_identities<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> > type;
  1151. BOOST_STATIC_CONSTANT(bool, value = (Traits::absorbs_identities));
  1152. };
  1153. template
  1154. <
  1155. class SubType,
  1156. class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc
  1157. >
  1158. struct is_total<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> >
  1159. {
  1160. typedef is_total<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> > type;
  1161. BOOST_STATIC_CONSTANT(bool, value = (Traits::is_total));
  1162. };
  1163. }} // namespace icl boost
  1164. #endif