interval_associator.hpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236
  1. /*-----------------------------------------------------------------------------+
  2. Copyright (c) 2010-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_CONCEPT_INTERVAL_ASSOCIATOR_HPP_JOFA_100920
  9. #define BOOST_ICL_CONCEPT_INTERVAL_ASSOCIATOR_HPP_JOFA_100920
  10. #include <boost/range/iterator_range.hpp>
  11. #include <boost/icl/type_traits/domain_type_of.hpp>
  12. #include <boost/icl/type_traits/interval_type_of.hpp>
  13. #include <boost/icl/type_traits/is_combinable.hpp>
  14. #include <boost/icl/detail/set_algo.hpp>
  15. #include <boost/icl/detail/map_algo.hpp>
  16. #include <boost/icl/detail/interval_set_algo.hpp>
  17. #include <boost/icl/detail/interval_map_algo.hpp>
  18. #include <boost/icl/concept/interval.hpp>
  19. namespace boost{ namespace icl
  20. {
  21. //==============================================================================
  22. //= Containedness<IntervalSet|IntervalMap>
  23. //==============================================================================
  24. //------------------------------------------------------------------------------
  25. //- bool within(c T&, c P&) T={Set,Map} P={e i b p S M}
  26. //------------------------------------------------------------------------------
  27. template<class SubT, class SuperT>
  28. typename enable_if<is_interval_container<SuperT>, bool>::type
  29. within(const SubT& sub, const SuperT& super)
  30. {
  31. return icl::contains(super, sub);
  32. }
  33. //==============================================================================
  34. //= Equivalences and Orderings<IntervalSet|IntervalMap>
  35. //==============================================================================
  36. template<class Type>
  37. inline typename enable_if<is_interval_container<Type>, bool>::type
  38. operator == (const Type& left, const Type& right)
  39. {
  40. return Set::lexicographical_equal(left, right);
  41. }
  42. template<class Type>
  43. inline typename enable_if<is_interval_container<Type>, bool>::type
  44. operator < (const Type& left, const Type& right)
  45. {
  46. typedef typename Type::segment_compare segment_compare;
  47. return std::lexicographical_compare(
  48. left.begin(), left.end(), right.begin(), right.end(),
  49. segment_compare()
  50. );
  51. }
  52. /** Returns true, if \c left and \c right contain the same elements.
  53. Complexity: linear. */
  54. template<class LeftT, class RightT>
  55. typename enable_if<is_intra_combinable<LeftT, RightT>, bool>::type
  56. is_element_equal(const LeftT& left, const RightT& right)
  57. {
  58. return Interval_Set::is_element_equal(left, right);
  59. }
  60. /** Returns true, if \c left is lexicographically less than \c right.
  61. Intervals are interpreted as sequence of elements.
  62. Complexity: linear. */
  63. template<class LeftT, class RightT>
  64. typename enable_if<is_intra_combinable<LeftT, RightT>, bool>::type
  65. is_element_less(const LeftT& left, const RightT& right)
  66. {
  67. return Interval_Set::is_element_less(left, right);
  68. }
  69. /** Returns true, if \c left is lexicographically greater than \c right.
  70. Intervals are interpreted as sequence of elements.
  71. Complexity: linear. */
  72. template<class LeftT, class RightT>
  73. typename enable_if<is_intra_combinable<LeftT, RightT>, bool>::type
  74. is_element_greater(const LeftT& left, const RightT& right)
  75. {
  76. return Interval_Set::is_element_greater(left, right);
  77. }
  78. //------------------------------------------------------------------------------
  79. template<class LeftT, class RightT>
  80. typename enable_if<is_inter_combinable<LeftT, RightT>, int>::type
  81. inclusion_compare(const LeftT& left, const RightT& right)
  82. {
  83. return Interval_Set::subset_compare(left, right,
  84. left.begin(), left.end(),
  85. right.begin(), right.end());
  86. }
  87. //------------------------------------------------------------------------------
  88. template<class LeftT, class RightT>
  89. typename enable_if< is_concept_compatible<is_interval_map, LeftT, RightT>,
  90. bool >::type
  91. is_distinct_equal(const LeftT& left, const RightT& right)
  92. {
  93. return Map::lexicographical_distinct_equal(left, right);
  94. }
  95. //==============================================================================
  96. //= Size<IntervalSet|IntervalMap>
  97. //==============================================================================
  98. template<class Type>
  99. typename enable_if<is_interval_container<Type>, std::size_t>::type
  100. iterative_size(const Type& object)
  101. {
  102. return object.iterative_size();
  103. }
  104. template<class Type>
  105. typename enable_if
  106. < mpl::and_< is_interval_container<Type>
  107. , is_discrete<typename Type::domain_type> >
  108. , typename Type::size_type
  109. >::type
  110. cardinality(const Type& object)
  111. {
  112. typedef typename Type::size_type size_type;
  113. //CL typedef typename Type::interval_type interval_type;
  114. size_type size = identity_element<size_type>::value();
  115. ICL_const_FORALL(typename Type, it, object)
  116. size += icl::cardinality(key_value<Type>(it));
  117. return size;
  118. }
  119. template<class Type>
  120. typename enable_if
  121. < mpl::and_< is_interval_container<Type>
  122. , mpl::not_<is_discrete<typename Type::domain_type> > >
  123. , typename Type::size_type
  124. >::type
  125. cardinality(const Type& object)
  126. {
  127. typedef typename Type::size_type size_type;
  128. //CL typedef typename Type::interval_type interval_type;
  129. size_type size = identity_element<size_type>::value();
  130. size_type interval_size;
  131. ICL_const_FORALL(typename Type, it, object)
  132. {
  133. interval_size = icl::cardinality(key_value<Type>(it));
  134. if(interval_size == icl::infinity<size_type>::value())
  135. return interval_size;
  136. else
  137. size += interval_size;
  138. }
  139. return size;
  140. }
  141. template<class Type>
  142. inline typename enable_if<is_interval_container<Type>, typename Type::size_type>::type
  143. size(const Type& object)
  144. {
  145. return icl::cardinality(object);
  146. }
  147. template<class Type>
  148. typename enable_if<is_interval_container<Type>, typename Type::difference_type>::type
  149. length(const Type& object)
  150. {
  151. typedef typename Type::difference_type difference_type;
  152. typedef typename Type::const_iterator const_iterator;
  153. difference_type length = identity_element<difference_type>::value();
  154. const_iterator it_ = object.begin();
  155. while(it_ != object.end())
  156. length += icl::length(key_value<Type>(it_++));
  157. return length;
  158. }
  159. template<class Type>
  160. typename enable_if<is_interval_container<Type>, std::size_t>::type
  161. interval_count(const Type& object)
  162. {
  163. return icl::iterative_size(object);
  164. }
  165. template<class Type>
  166. typename enable_if< is_interval_container<Type>
  167. , typename Type::difference_type >::type
  168. distance(const Type& object)
  169. {
  170. typedef typename Type::difference_type DiffT;
  171. typedef typename Type::const_iterator const_iterator;
  172. const_iterator it_ = object.begin(), pred_;
  173. DiffT dist = identity_element<DiffT>::value();
  174. if(it_ != object.end())
  175. pred_ = it_++;
  176. while(it_ != object.end())
  177. dist += icl::distance(key_value<Type>(pred_++), key_value<Type>(it_++));
  178. return dist;
  179. }
  180. //==============================================================================
  181. //= Range<IntervalSet|IntervalMap>
  182. //==============================================================================
  183. template<class Type>
  184. typename enable_if<is_interval_container<Type>,
  185. typename Type::interval_type>::type
  186. hull(const Type& object)
  187. {
  188. return
  189. icl::is_empty(object)
  190. ? identity_element<typename Type::interval_type>::value()
  191. : icl::hull( key_value<Type>(object.begin()),
  192. key_value<Type>(object.rbegin()) );
  193. }
  194. template<class Type>
  195. typename enable_if<is_interval_container<Type>,
  196. typename domain_type_of<Type>::type>::type
  197. lower(const Type& object)
  198. {
  199. typedef typename domain_type_of<Type>::type DomainT;
  200. return
  201. icl::is_empty(object)
  202. ? unit_element<DomainT>::value()
  203. : icl::lower( key_value<Type>(object.begin()) );
  204. }
  205. template<class Type>
  206. typename enable_if<is_interval_container<Type>,
  207. typename domain_type_of<Type>::type>::type
  208. upper(const Type& object)
  209. {
  210. typedef typename domain_type_of<Type>::type DomainT;
  211. return
  212. icl::is_empty(object)
  213. ? identity_element<DomainT>::value()
  214. : icl::upper( key_value<Type>(object.rbegin()) );
  215. }
  216. //------------------------------------------------------------------------------
  217. template<class Type>
  218. typename enable_if
  219. < mpl::and_< is_interval_container<Type>
  220. , is_discrete<typename domain_type_of<Type>::type> >
  221. , typename domain_type_of<Type>::type>::type
  222. first(const Type& object)
  223. {
  224. typedef typename domain_type_of<Type>::type DomainT;
  225. return
  226. icl::is_empty(object)
  227. ? unit_element<DomainT>::value()
  228. : icl::first( key_value<Type>(object.begin()) );
  229. }
  230. template<class Type>
  231. typename enable_if
  232. < mpl::and_< is_interval_container<Type>
  233. , is_discrete<typename domain_type_of<Type>::type> >
  234. , typename domain_type_of<Type>::type>::type
  235. last(const Type& object)
  236. {
  237. typedef typename domain_type_of<Type>::type DomainT;
  238. return
  239. icl::is_empty(object)
  240. ? identity_element<DomainT>::value()
  241. : icl::last( key_value<Type>(object.rbegin()) );
  242. }
  243. //==============================================================================
  244. //= Addition<IntervalSet|IntervalMap>
  245. //==============================================================================
  246. //------------------------------------------------------------------------------
  247. //- T& op +=(T&, c P&) T:{S}|{M} P:{e i}|{b p}
  248. //------------------------------------------------------------------------------
  249. /* \par \b Requires: \c OperandT is an addable derivative type of \c Type.
  250. \b Effects: \c operand is added to \c object.
  251. \par \b Returns: A reference to \c object.
  252. \b Complexity:
  253. \code
  254. \ OperandT:
  255. \ element segment
  256. Type:
  257. interval container O(log n) O(n)
  258. interval_set amortized
  259. spearate_interval_set O(log n)
  260. n = object.interval_count()
  261. \endcode
  262. For the addition of \b elements or \b segments
  263. complexity is \b logarithmic or \b linear respectively.
  264. For \c interval_sets and \c separate_interval_sets addition of segments
  265. is \b amortized \b logarithmic.
  266. */
  267. template<class Type, class OperandT>
  268. typename enable_if<is_intra_derivative<Type, OperandT>, Type>::type&
  269. operator += (Type& object, const OperandT& operand)
  270. {
  271. return icl::add(object, operand);
  272. }
  273. //------------------------------------------------------------------------------
  274. //- T& op +=(T&, c P&) T:{S}|{M} P:{S'}|{M'}
  275. //------------------------------------------------------------------------------
  276. /** \par \b Requires: \c OperandT is an interval container addable to \c Type.
  277. \b Effects: \c operand is added to \c object.
  278. \par \b Returns: A reference to \c object.
  279. \b Complexity: loglinear */
  280. template<class Type, class OperandT>
  281. typename enable_if<is_intra_combinable<Type, OperandT>, Type>::type&
  282. operator += (Type& object, const OperandT& operand)
  283. {
  284. typename Type::iterator prior_ = object.end();
  285. ICL_const_FORALL(typename OperandT, elem_, operand)
  286. prior_ = icl::add(object, prior_, *elem_);
  287. return object;
  288. }
  289. #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  290. //------------------------------------------------------------------------------
  291. //- T op + (T, c P&) T:{S}|{M} P:{e i S}|{b p M}
  292. //------------------------------------------------------------------------------
  293. /** \par \b Requires: \c object and \c operand are addable.
  294. \b Effects: \c operand is added to \c object.
  295. \par \b Efficieny: There is one additional copy of
  296. \c Type \c object compared to inplace \c operator \c += */
  297. template<class Type, class OperandT>
  298. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  299. operator + (Type object, const OperandT& operand)
  300. {
  301. return object += operand;
  302. }
  303. #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  304. template<class Type, class OperandT>
  305. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  306. operator + (const Type& object, const OperandT& operand)
  307. {
  308. Type temp = object;
  309. return boost::move(temp += operand);
  310. }
  311. template<class Type, class OperandT>
  312. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  313. operator + (Type&& object, const OperandT& operand)
  314. {
  315. return boost::move(object += operand);
  316. }
  317. #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  318. #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  319. //------------------------------------------------------------------------------
  320. //- T op + (c P&, T) T:{S}|{M} P:{e i S'}|{b p M'}
  321. //------------------------------------------------------------------------------
  322. /** \par \b Requires: \c object and \c operand are addable.
  323. \b Effects: \c operand is added to \c object.
  324. \par \b Efficieny: There is one additional copy of
  325. \c Type \c object compared to inplace \c operator \c += */
  326. template<class Type, class OperandT>
  327. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  328. operator + (const OperandT& operand, Type object)
  329. {
  330. return object += operand;
  331. }
  332. #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  333. template<class Type, class OperandT>
  334. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  335. operator + (const OperandT& operand, const Type& object)
  336. {
  337. Type temp = object;
  338. return boost::move(temp += operand);
  339. }
  340. template<class Type, class OperandT>
  341. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  342. operator + (const OperandT& operand, Type&& object)
  343. {
  344. return boost::move(object += operand);
  345. }
  346. #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  347. #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  348. //------------------------------------------------------------------------------
  349. //- T op + (T, c P&) T:{S}|{M} P:{S}|{M}
  350. //------------------------------------------------------------------------------
  351. /** \par \b Requires: \c object and \c operand are addable.
  352. \b Effects: \c operand is added to \c object.
  353. \par \b Efficieny: There is one additional copy of
  354. \c Type \c object compared to inplace \c operator \c += */
  355. template<class Type>
  356. typename enable_if<is_interval_container<Type>, Type>::type
  357. operator + (Type object, const Type& operand)
  358. {
  359. return object += operand;
  360. }
  361. #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  362. template<class Type>
  363. typename enable_if<is_interval_container<Type>, Type>::type
  364. operator + (const Type& object, const Type& operand)
  365. {
  366. Type temp = object;
  367. return boost::move(temp += operand);
  368. }
  369. template<class Type>
  370. typename enable_if<is_interval_container<Type>, Type>::type
  371. operator + (Type&& object, const Type& operand)
  372. {
  373. return boost::move(object += operand);
  374. }
  375. template<class Type>
  376. typename enable_if<is_interval_container<Type>, Type>::type
  377. operator + (const Type& operand, Type&& object)
  378. {
  379. return boost::move(object += operand);
  380. }
  381. template<class Type>
  382. typename enable_if<is_interval_container<Type>, Type>::type
  383. operator + (Type&& object, Type&& operand)
  384. {
  385. return boost::move(object += operand);
  386. }
  387. #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  388. //------------------------------------------------------------------------------
  389. //- Addition |=, |
  390. //------------------------------------------------------------------------------
  391. //------------------------------------------------------------------------------
  392. //- T& op |=(c P&) T:{S}|{M} P:{e i}|{b p}
  393. //------------------------------------------------------------------------------
  394. /** \par \b Requires: Types \c Type and \c OperandT are addable.
  395. \par \b Effects: \c operand is added to \c object.
  396. \par \b Returns: A reference to \c object.
  397. \b Complexity:
  398. \code
  399. \ OperandT: interval
  400. \ element segment container
  401. Type:
  402. interval container O(log n) O(n) O(m log(n+m))
  403. interval_set amortized
  404. spearate_interval_set O(log n)
  405. n = object.interval_count()
  406. m = operand.interval_count()
  407. \endcode
  408. For the addition of \b elements, \b segments and \b interval \b containers
  409. complexity is \b logarithmic, \b linear and \b loglinear respectively.
  410. For \c interval_sets and \c separate_interval_sets addition of segments
  411. is \b amortized \b logarithmic.
  412. */
  413. template<class Type, class OperandT>
  414. typename enable_if<is_right_intra_combinable<Type, OperandT>, Type>::type&
  415. operator |= (Type& object, const OperandT& operand)
  416. {
  417. return object += operand;
  418. }
  419. #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  420. //------------------------------------------------------------------------------
  421. //- T op | (T, c P&) T:{S}|{M} P:{e i S}|{b p M}
  422. //------------------------------------------------------------------------------
  423. /** \par \b Requires: \c object and \c operand are addable.
  424. \b Effects: \c operand is added to \c object.
  425. \par \b Efficieny: There is one additional copy of
  426. \c Type \c object compared to inplace \c operator \c |= */
  427. template<class Type, class OperandT>
  428. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  429. operator | (Type object, const OperandT& operand)
  430. {
  431. return object += operand;
  432. }
  433. #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  434. template<class Type, class OperandT>
  435. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  436. operator | (const Type& object, const OperandT& operand)
  437. {
  438. Type temp = object;
  439. return boost::move(temp += operand);
  440. }
  441. template<class Type, class OperandT>
  442. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  443. operator | (Type&& object, const OperandT& operand)
  444. {
  445. return boost::move(object += operand);
  446. }
  447. #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  448. #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  449. //------------------------------------------------------------------------------
  450. //- T op | (T, c P&) T:{S}|{M} P:{S}|{M}
  451. //------------------------------------------------------------------------------
  452. /** \par \b Requires: \c object and \c operand are addable.
  453. \b Effects: \c operand is added to \c object.
  454. \par \b Efficieny: There is one additional copy of
  455. \c Type \c object compared to inplace \c operator \c |= */
  456. template<class Type, class OperandT>
  457. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  458. operator | (const OperandT& operand, Type object)
  459. {
  460. return object += operand;
  461. }
  462. #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  463. template<class Type, class OperandT>
  464. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  465. operator | (const OperandT& operand, const Type& object)
  466. {
  467. Type temp = object;
  468. return boost::move(temp += operand);
  469. }
  470. template<class Type, class OperandT>
  471. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  472. operator | (const OperandT& operand, Type&& object)
  473. {
  474. return boost::move(object += operand);
  475. }
  476. #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  477. #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  478. //------------------------------------------------------------------------------
  479. //- T op | (T, c P&) T:{S}|{M} P:{S}|{M}
  480. //------------------------------------------------------------------------------
  481. /** \par \b Requires: \c object and \c operand are addable.
  482. \b Effects: \c operand is added to \c object.
  483. \par \b Efficieny: There is one additional copy of
  484. \c Type \c object compared to inplace \c operator \c |= */
  485. template<class Type>
  486. typename enable_if<is_interval_container<Type>, Type>::type
  487. operator | (Type object, const Type& operand)
  488. {
  489. return object += operand;
  490. }
  491. #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  492. template<class Type>
  493. typename enable_if<is_interval_container<Type>, Type>::type
  494. operator | (const Type& object, const Type& operand)
  495. {
  496. Type temp = object;
  497. return boost::move(temp += operand);
  498. }
  499. template<class Type>
  500. typename enable_if<is_interval_container<Type>, Type>::type
  501. operator | (Type&& object, const Type& operand)
  502. {
  503. return boost::move(object += operand);
  504. }
  505. template<class Type>
  506. typename enable_if<is_interval_container<Type>, Type>::type
  507. operator | (const Type& operand, Type&& object)
  508. {
  509. return boost::move(object += operand);
  510. }
  511. template<class Type>
  512. typename enable_if<is_interval_container<Type>, Type>::type
  513. operator | (Type&& object, Type&& operand)
  514. {
  515. return boost::move(object += operand);
  516. }
  517. #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  518. //==============================================================================
  519. //= Insertion<IntervalSet|IntervalSet>
  520. //==============================================================================
  521. //------------------------------------------------------------------------------
  522. //- T& insert(T&, c P&) T:{S}|{M} P:{S'}|{M'}
  523. //------------------------------------------------------------------------------
  524. template<class Type, class OperandT>
  525. typename enable_if<is_intra_combinable<Type, OperandT>, Type>::type&
  526. insert(Type& object, const OperandT& operand)
  527. {
  528. typename Type::iterator prior_ = object.end();
  529. ICL_const_FORALL(typename OperandT, elem_, operand)
  530. insert(object, prior_, *elem_);
  531. return object;
  532. }
  533. //==============================================================================
  534. //= Erasure<IntervalSet|IntervalSet>
  535. //==============================================================================
  536. //------------------------------------------------------------------------------
  537. //- T& erase(T&, c P&) T:{S}|{M} P:{S'}|{S' M'}
  538. //------------------------------------------------------------------------------
  539. template<class Type, class OperandT>
  540. typename enable_if<combines_right_to_interval_container<Type, OperandT>,
  541. Type>::type&
  542. erase(Type& object, const OperandT& operand)
  543. {
  544. typedef typename OperandT::const_iterator const_iterator;
  545. if(icl::is_empty(operand))
  546. return object;
  547. const_iterator common_lwb, common_upb;
  548. if(!Set::common_range(common_lwb, common_upb, operand, object))
  549. return object;
  550. const_iterator it_ = common_lwb;
  551. while(it_ != common_upb)
  552. icl::erase(object, *it_++);
  553. return object;
  554. }
  555. //==============================================================================
  556. //= Subtraction<IntervalSet|IntervalSet>
  557. //==============================================================================
  558. //------------------------------------------------------------------------------
  559. //- T& op -= (c P&) T:{M} P:{M'}
  560. //------------------------------------------------------------------------------
  561. /** \par \b Requires: Types \c Type and \c OperandT are subtractable.
  562. \par \b Effects: \c operand is subtracted from \c object.
  563. \par \b Returns: A reference to \c object.
  564. \b Complexity:
  565. \code
  566. \ OperandT: interval
  567. \ element segment container
  568. Type:
  569. interval container O(log n) O(n) O(m log(n+m))
  570. amortized
  571. interval_sets O(log n)
  572. n = object.interval_count()
  573. m = operand.interval_count()
  574. \endcode
  575. For the subtraction of \em elements, \b segments and \b interval \b containers
  576. complexity is \b logarithmic, \b linear and \b loglinear respectively.
  577. For interval sets subtraction of segments
  578. is \b amortized \b logarithmic.
  579. */
  580. template<class Type, class OperandT>
  581. typename enable_if<is_concept_compatible<is_interval_map, Type, OperandT>,
  582. Type>::type&
  583. operator -=(Type& object, const OperandT& operand)
  584. {
  585. ICL_const_FORALL(typename OperandT, elem_, operand)
  586. icl::subtract(object, *elem_);
  587. return object;
  588. }
  589. //------------------------------------------------------------------------------
  590. //- T& op -= (c P&) T:{S}|{M} P:{e i}|{b p}
  591. //------------------------------------------------------------------------------
  592. template<class Type, class OperandT>
  593. typename enable_if<is_intra_derivative<Type, OperandT>, Type>::type&
  594. operator -= (Type& object, const OperandT& operand)
  595. {
  596. return icl::subtract(object, operand);
  597. }
  598. //------------------------------------------------------------------------------
  599. //- T& op -= (c P&) T:{M} P:{e i}
  600. //------------------------------------------------------------------------------
  601. template<class Type, class OperandT>
  602. typename enable_if<is_cross_derivative<Type, OperandT>, Type>::type&
  603. operator -= (Type& object, const OperandT& operand)
  604. {
  605. return icl::erase(object, operand);
  606. }
  607. //------------------------------------------------------------------------------
  608. //- T& op -= (c P&) T:{S M} P:{S'}
  609. //------------------------------------------------------------------------------
  610. template<class Type, class IntervalSetT>
  611. typename enable_if<combines_right_to_interval_set<Type, IntervalSetT>,
  612. Type>::type&
  613. operator -= (Type& object, const IntervalSetT& operand)
  614. {
  615. return erase(object, operand);
  616. }
  617. #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  618. //------------------------------------------------------------------------------
  619. //- T op - (T, c P&) T:{S}|{M} P:{e i S'}|{e i b p S' M'}
  620. //------------------------------------------------------------------------------
  621. template<class Type, class OperandT>
  622. typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type
  623. operator - (Type object, const OperandT& operand)
  624. {
  625. return object -= operand;
  626. }
  627. #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  628. template<class Type, class OperandT>
  629. typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type
  630. operator - (const Type& object, const OperandT& operand)
  631. {
  632. Type temp = object;
  633. return boost::move(temp -= operand);
  634. }
  635. template<class Type, class OperandT>
  636. typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type
  637. operator - (Type&& object, const OperandT& operand)
  638. {
  639. return boost::move(object -= operand);
  640. }
  641. #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  642. //==============================================================================
  643. //= Intersection<IntervalSet|IntervalSet>
  644. //==============================================================================
  645. //------------------------------------------------------------------------------
  646. //- void add_intersection(T&, c T&, c P&) T:{S M} P:{S'}
  647. //------------------------------------------------------------------------------
  648. template<class Type, class OperandT>
  649. typename enable_if<mpl::and_<is_interval_set<Type>,
  650. combines_right_to_interval_set<Type, OperandT> >,
  651. void>::type
  652. add_intersection(Type& section, const Type& object, const OperandT& operand)
  653. {
  654. typedef typename OperandT::const_iterator const_iterator;
  655. if(operand.empty())
  656. return;
  657. const_iterator common_lwb, common_upb;
  658. if(!Set::common_range(common_lwb, common_upb, operand, object))
  659. return;
  660. const_iterator it_ = common_lwb;
  661. while(it_ != common_upb)
  662. icl::add_intersection(section, object, key_value<OperandT>(it_++));
  663. }
  664. //------------------------------------------------------------------------------
  665. //- T& op &=(T&, c P&) T:{S}|{M} P:{e i S'}|{e i b p S' M'}
  666. //------------------------------------------------------------------------------
  667. template<class Type, class OperandT>
  668. typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type&
  669. operator &= (Type& object, const OperandT& operand)
  670. {
  671. Type intersection;
  672. add_intersection(intersection, object, operand);
  673. object.swap(intersection);
  674. return object;
  675. }
  676. #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  677. //------------------------------------------------------------------------------
  678. //- T op & (T, c P&) T:{S}|{M} P:{e i S'}|{e i b p S' M'} S<S' M<M' <:coarser
  679. //------------------------------------------------------------------------------
  680. template<class Type, class OperandT>
  681. typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
  682. operator & (Type object, const OperandT& operand)
  683. {
  684. return object &= operand;
  685. }
  686. #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  687. template<class Type, class OperandT>
  688. typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
  689. operator & (const Type& object, const OperandT& operand)
  690. {
  691. Type temp = object;
  692. return boost::move(temp &= operand);
  693. }
  694. template<class Type, class OperandT>
  695. typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
  696. operator & (Type&& object, const OperandT& operand)
  697. {
  698. return boost::move(object &= operand);
  699. }
  700. #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  701. #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  702. //------------------------------------------------------------------------------
  703. //- T op & (c P&, T) T:{S}|{M} P:{e i S'}|{e i b p S' M'} S<S' M<M' <:coarser
  704. //------------------------------------------------------------------------------
  705. template<class Type, class OperandT>
  706. typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
  707. operator & (const OperandT& operand, Type object)
  708. {
  709. return object &= operand;
  710. }
  711. #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  712. template<class Type, class OperandT>
  713. typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
  714. operator & (const OperandT& operand, const Type& object)
  715. {
  716. Type temp = object;
  717. return boost::move(temp &= operand);
  718. }
  719. template<class Type, class OperandT>
  720. typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
  721. operator & (const OperandT& operand, Type&& object)
  722. {
  723. return boost::move(object &= operand);
  724. }
  725. #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  726. #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  727. //------------------------------------------------------------------------------
  728. //- T op & (T, c T&) T:{S M}
  729. //------------------------------------------------------------------------------
  730. template<class Type>
  731. typename enable_if<is_interval_container<Type>, Type>::type
  732. operator & (Type object, const Type& operand)
  733. {
  734. return object &= operand;
  735. }
  736. #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  737. template<class Type>
  738. typename enable_if<is_interval_container<Type>, Type>::type
  739. operator & (const Type& object, const Type& operand)
  740. {
  741. Type temp = object;
  742. return boost::move(temp &= operand);
  743. }
  744. template<class Type>
  745. typename enable_if<is_interval_container<Type>, Type>::type
  746. operator & (Type&& object, const Type& operand)
  747. {
  748. return boost::move(object &= operand);
  749. }
  750. template<class Type>
  751. typename enable_if<is_interval_container<Type>, Type>::type
  752. operator & (const Type& operand, Type&& object)
  753. {
  754. return boost::move(object &= operand);
  755. }
  756. template<class Type>
  757. typename enable_if<is_interval_container<Type>, Type>::type
  758. operator & (Type&& object, Type&& operand)
  759. {
  760. return boost::move(object &= operand);
  761. }
  762. #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  763. //------------------------------------------------------------------------------
  764. //- intersects<IntervalSet|IntervalMap>
  765. //------------------------------------------------------------------------------
  766. //------------------------------------------------------------------------------
  767. //- bool intersects(c T&, c P&) T:{S}|{M} P:{e i}
  768. //------------------------------------------------------------------------------
  769. template<class Type, class CoType>
  770. typename enable_if<mpl::and_< is_interval_container<Type>
  771. , boost::is_same<CoType, typename domain_type_of<Type>::type> >,
  772. bool>::type
  773. intersects(const Type& left, const CoType& right)
  774. {
  775. return icl::contains(left, right);
  776. }
  777. template<class Type, class CoType>
  778. typename enable_if<mpl::and_< is_interval_container<Type>
  779. , boost::is_same<CoType, typename interval_type_of<Type>::type> >,
  780. bool>::type
  781. intersects(const Type& left, const CoType& right)
  782. {
  783. return icl::find(left, right) != left.end();
  784. }
  785. template<class LeftT, class RightT>
  786. typename enable_if< mpl::and_< is_intra_combinable<LeftT, RightT>
  787. , mpl::or_<is_total<LeftT>, is_total<RightT> > >
  788. , bool>::type
  789. intersects(const LeftT&, const RightT&)
  790. {
  791. return true;
  792. }
  793. template<class LeftT, class RightT>
  794. typename enable_if< mpl::and_< is_intra_combinable<LeftT, RightT>
  795. , mpl::not_<mpl::or_< is_total<LeftT>
  796. , is_total<RightT> > > >
  797. , bool>::type
  798. intersects(const LeftT& left, const RightT& right)
  799. {
  800. typedef typename RightT::const_iterator const_iterator;
  801. LeftT intersection;
  802. const_iterator right_common_lower_, right_common_upper_;
  803. if(!Set::common_range(right_common_lower_, right_common_upper_, right, left))
  804. return false;
  805. const_iterator it_ = right_common_lower_;
  806. while(it_ != right_common_upper_)
  807. {
  808. icl::add_intersection(intersection, left, *it_++);
  809. if(!icl::is_empty(intersection))
  810. return true;
  811. }
  812. return false;
  813. }
  814. template<class LeftT, class RightT>
  815. typename enable_if<is_cross_combinable<LeftT, RightT>, bool>::type
  816. intersects(const LeftT& left, const RightT& right)
  817. {
  818. typedef typename RightT::const_iterator const_iterator;
  819. LeftT intersection;
  820. if(icl::is_empty(left) || icl::is_empty(right))
  821. return false;
  822. const_iterator right_common_lower_, right_common_upper_;
  823. if(!Set::common_range(right_common_lower_, right_common_upper_, right, left))
  824. return false;
  825. typename RightT::const_iterator it_ = right_common_lower_;
  826. while(it_ != right_common_upper_)
  827. {
  828. icl::add_intersection(intersection, left, key_value<RightT>(it_++));
  829. if(!icl::is_empty(intersection))
  830. return true;
  831. }
  832. return false;
  833. }
  834. /** \b Returns true, if \c left and \c right have no common elements.
  835. Intervals are interpreted as sequence of elements.
  836. \b Complexity: loglinear, if \c left and \c right are interval containers. */
  837. template<class LeftT, class RightT>
  838. typename enable_if<is_inter_combinable<LeftT, RightT>, bool>::type
  839. disjoint(const LeftT& left, const RightT& right)
  840. {
  841. return !intersects(left, right);
  842. }
  843. /** \b Returns true, if \c left and \c right have no common elements.
  844. Intervals are interpreted as sequence of elements.
  845. \b Complexity: logarithmic, if \c AssociateT is an element type \c Type::element_type.
  846. linear, if \c AssociateT is a segment type \c Type::segment_type. */
  847. template<class Type, class AssociateT>
  848. typename enable_if<is_inter_derivative<Type, AssociateT>, bool>::type
  849. disjoint(const Type& left, const AssociateT& right)
  850. {
  851. return !intersects(left,right);
  852. }
  853. //==============================================================================
  854. //= Symmetric difference<IntervalSet|IntervalSet>
  855. //==============================================================================
  856. //------------------------------------------------------------------------------
  857. //- Symmetric difference ^=, ^
  858. //------------------------------------------------------------------------------
  859. //------------------------------------------------------------------------------
  860. //- T& op ^=(T&, c P&) T:{S}|{M} P:{S'}|{M'}
  861. //------------------------------------------------------------------------------
  862. template<class Type, class OperandT>
  863. typename enable_if<is_intra_combinable<Type, OperandT>, Type>::type&
  864. operator ^= (Type& object, const OperandT& operand)
  865. {
  866. return icl::flip(object, operand);
  867. }
  868. //------------------------------------------------------------------------------
  869. //- T& op ^=(T&, c P&) T:{S}|{M} P:{e i}|{b p}
  870. //------------------------------------------------------------------------------
  871. template<class Type, class OperandT>
  872. typename enable_if<is_intra_derivative<Type, OperandT>, Type>::type&
  873. operator ^= (Type& object, const OperandT& operand)
  874. {
  875. return icl::flip(object, operand);
  876. }
  877. #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  878. //------------------------------------------------------------------------------
  879. //- T op ^ (T, c P&) T:{S}|{M} P:{e i S'}|{b p M'} S<S' M<M' <:coarser
  880. //------------------------------------------------------------------------------
  881. template<class Type, class OperandT>
  882. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  883. operator ^ (Type object, const OperandT& operand)
  884. {
  885. return object ^= operand;
  886. }
  887. #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  888. template<class Type, class OperandT>
  889. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  890. operator ^ (const Type& object, const OperandT& operand)
  891. {
  892. Type temp = object;
  893. return boost::move(temp ^= operand);
  894. }
  895. template<class Type, class OperandT>
  896. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  897. operator ^ (Type&& object, const OperandT& operand)
  898. {
  899. return boost::move(object ^= operand);
  900. }
  901. #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  902. #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  903. //------------------------------------------------------------------------------
  904. //- T op ^ (c P&, T) T:{S}|{M} P:{e i S'}|{b p M'} S<S' M<M' <:coarser
  905. //------------------------------------------------------------------------------
  906. template<class Type, class OperandT>
  907. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  908. operator ^ (const OperandT& operand, Type object)
  909. {
  910. return object ^= operand;
  911. }
  912. #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  913. template<class Type, class OperandT>
  914. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  915. operator ^ (const OperandT& operand, const Type& object)
  916. {
  917. Type temp = object;
  918. return boost::move(temp ^= operand);
  919. }
  920. template<class Type, class OperandT>
  921. typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
  922. operator ^ (const OperandT& operand, Type&& object)
  923. {
  924. return boost::move(object ^= operand);
  925. }
  926. #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  927. #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  928. //------------------------------------------------------------------------------
  929. //- T op ^ (T, c T&) T:{S M}
  930. //------------------------------------------------------------------------------
  931. template<class Type>
  932. typename enable_if<is_interval_container<Type>, Type>::type
  933. operator ^ (typename Type::overloadable_type object, const Type& operand)
  934. {
  935. return object ^= operand;
  936. }
  937. #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  938. template<class Type>
  939. typename enable_if<is_interval_container<Type>, Type>::type
  940. operator ^ (const Type& object, const Type& operand)
  941. {
  942. Type temp = object;
  943. return boost::move(temp ^= operand);
  944. }
  945. template<class Type>
  946. typename enable_if<is_interval_container<Type>, Type>::type
  947. operator ^ (Type&& object, const Type& operand)
  948. {
  949. return boost::move(object ^= operand);
  950. }
  951. template<class Type>
  952. typename enable_if<is_interval_container<Type>, Type>::type
  953. operator ^ (const Type& operand, Type&& object)
  954. {
  955. return boost::move(object ^= operand);
  956. }
  957. template<class Type>
  958. typename enable_if<is_interval_container<Type>, Type>::type
  959. operator ^ (Type&& object, Type&& operand)
  960. {
  961. return boost::move(object ^= operand);
  962. }
  963. #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
  964. //==========================================================================
  965. //= Element Iteration <IntervalSet|IntervalMap>
  966. //==========================================================================
  967. //--------------------------------------------------------------------------
  968. //- Forward
  969. //--------------------------------------------------------------------------
  970. template<class Type>
  971. typename enable_if
  972. <mpl::and_< is_interval_container<Type>
  973. , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
  974. typename Type::element_iterator>::type
  975. elements_begin(Type& object)
  976. {
  977. return typename Type::element_iterator(object.begin());
  978. }
  979. template<class Type>
  980. typename enable_if
  981. <mpl::and_< is_interval_container<Type>
  982. , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
  983. typename Type::element_iterator>::type
  984. elements_end(Type& object)
  985. {
  986. return typename Type::element_iterator(object.end());
  987. }
  988. template<class Type>
  989. typename enable_if
  990. <mpl::and_< is_interval_container<Type>
  991. , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
  992. typename Type::element_const_iterator>::type
  993. elements_begin(const Type& object)
  994. {
  995. return typename Type::element_const_iterator(object.begin());
  996. }
  997. template<class Type>
  998. typename enable_if
  999. <mpl::and_< is_interval_container<Type>
  1000. , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
  1001. typename Type::element_const_iterator>::type
  1002. elements_end(const Type& object)
  1003. {
  1004. return typename Type::element_const_iterator(object.end());
  1005. }
  1006. template<class Type>
  1007. typename enable_if
  1008. <mpl::and_< is_interval_container<Type>
  1009. , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
  1010. iterator_range<typename Type::element_iterator> >::type
  1011. elements(Type& object)
  1012. {
  1013. return
  1014. make_iterator_range( typename Type::element_iterator(object.begin())
  1015. , typename Type::element_iterator(object.end()) );
  1016. }
  1017. template<class Type>
  1018. typename enable_if
  1019. <mpl::and_< is_interval_container<Type>
  1020. , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
  1021. iterator_range<typename Type::element_const_iterator> >::type
  1022. elements(Type const& object)
  1023. {
  1024. return
  1025. make_iterator_range( typename Type::element_const_iterator(object.begin())
  1026. , typename Type::element_const_iterator(object.end()) );
  1027. }
  1028. //--------------------------------------------------------------------------
  1029. //- Reverse
  1030. //--------------------------------------------------------------------------
  1031. template<class Type>
  1032. typename enable_if
  1033. <mpl::and_< is_interval_container<Type>
  1034. , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
  1035. typename Type::element_reverse_iterator>::type
  1036. elements_rbegin(Type& object)
  1037. {
  1038. return typename Type::element_reverse_iterator(object.rbegin());
  1039. }
  1040. template<class Type>
  1041. typename enable_if
  1042. <mpl::and_< is_interval_container<Type>
  1043. , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
  1044. typename Type::element_reverse_iterator>::type
  1045. elements_rend(Type& object)
  1046. {
  1047. return typename Type::element_reverse_iterator(object.rend());
  1048. }
  1049. template<class Type>
  1050. typename enable_if
  1051. <mpl::and_< is_interval_container<Type>
  1052. , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
  1053. typename Type::element_const_reverse_iterator>::type
  1054. elements_rbegin(const Type& object)
  1055. {
  1056. return typename Type::element_const_reverse_iterator(object.rbegin());
  1057. }
  1058. template<class Type>
  1059. typename enable_if
  1060. <mpl::and_< is_interval_container<Type>
  1061. , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
  1062. typename Type::element_const_reverse_iterator>::type
  1063. elements_rend(const Type& object)
  1064. {
  1065. return typename Type::element_const_reverse_iterator(object.rend());
  1066. }
  1067. }} // namespace boost icl
  1068. #endif