interval_map_algo.hpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*-----------------------------------------------------------------------------+
  2. Copyright (c) 2008-2010: Joachim Faulhaber
  3. +------------------------------------------------------------------------------+
  4. Distributed under the Boost Software License, Version 1.0.
  5. (See accompanying file LICENCE.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. +-----------------------------------------------------------------------------*/
  8. #ifndef BOOST_ICL_INTERVAL_MAP_ALGO_HPP_JOFA_100730
  9. #define BOOST_ICL_INTERVAL_MAP_ALGO_HPP_JOFA_100730
  10. #include <boost/utility/enable_if.hpp>
  11. #include <boost/mpl/not.hpp>
  12. #include <boost/icl/type_traits/is_total.hpp>
  13. #include <boost/icl/type_traits/is_map.hpp>
  14. #include <boost/icl/detail/notate.hpp>
  15. #include <boost/icl/detail/relation_state.hpp>
  16. #include <boost/icl/type_traits/identity_element.hpp>
  17. #include <boost/icl/interval_combining_style.hpp>
  18. #include <boost/icl/detail/element_comparer.hpp>
  19. #include <boost/icl/detail/interval_subset_comparer.hpp>
  20. namespace boost{namespace icl
  21. {
  22. namespace Interval_Map
  23. {
  24. using namespace segmental;
  25. template<class IntervalMapT>
  26. bool is_joinable(const IntervalMapT& container,
  27. typename IntervalMapT::const_iterator first,
  28. typename IntervalMapT::const_iterator past)
  29. {
  30. if(first == container.end())
  31. return true;
  32. typename IntervalMapT::const_iterator it_ = first, next_ = first;
  33. ++next_;
  34. const typename IntervalMapT::codomain_type& co_value
  35. = icl::co_value<IntervalMapT>(first);
  36. while(it_ != past)
  37. {
  38. if(icl::co_value<IntervalMapT>(next_) != co_value)
  39. return false;
  40. if(!icl::touches(key_value<IntervalMapT>(it_++),
  41. key_value<IntervalMapT>(next_++)))
  42. return false;
  43. }
  44. return true;
  45. }
  46. //------------------------------------------------------------------------------
  47. //- Containedness of key objects
  48. //------------------------------------------------------------------------------
  49. //- domain_type ----------------------------------------------------------------
  50. template<class IntervalMapT>
  51. typename enable_if<mpl::not_<is_total<IntervalMapT> >, bool>::type
  52. contains(const IntervalMapT& container,
  53. const typename IntervalMapT::domain_type& key)
  54. {
  55. return container.find(key) != container.end();
  56. }
  57. template<class IntervalMapT>
  58. typename enable_if<is_total<IntervalMapT>, bool>::type
  59. contains(const IntervalMapT&,
  60. const typename IntervalMapT::domain_type&)
  61. {
  62. return true;
  63. }
  64. //- interval_type --------------------------------------------------------------
  65. template<class IntervalMapT>
  66. typename enable_if<mpl::not_<is_total<IntervalMapT> >, bool>::type
  67. contains(const IntervalMapT& container,
  68. const typename IntervalMapT::interval_type& sub_interval)
  69. {
  70. typedef typename IntervalMapT::const_iterator const_iterator;
  71. if(icl::is_empty(sub_interval))
  72. return true;
  73. std::pair<const_iterator, const_iterator> exterior = container.equal_range(sub_interval);
  74. if(exterior.first == exterior.second)
  75. return false;
  76. const_iterator last_overlap = prior(exterior.second);
  77. return
  78. icl::contains(hull(exterior.first->first, last_overlap->first), sub_interval)
  79. && Interval_Set::is_joinable(container, exterior.first, last_overlap);
  80. }
  81. template<class IntervalMapT>
  82. typename enable_if<is_total<IntervalMapT>, bool>::type
  83. contains(const IntervalMapT&,
  84. const typename IntervalMapT::interval_type&)
  85. {
  86. return true;
  87. }
  88. //- set_type -------------------------------------------------------------------
  89. template<class IntervalMapT, class IntervalSetT>
  90. typename enable_if<mpl::and_<mpl::not_<is_total<IntervalMapT> >
  91. ,is_interval_set<IntervalSetT> >, bool>::type
  92. contains(const IntervalMapT& super_map, const IntervalSetT& sub_set)
  93. {
  94. return Interval_Set::within(sub_set, super_map);
  95. }
  96. template<class IntervalMapT, class IntervalSetT>
  97. typename enable_if<mpl::and_<is_total<IntervalMapT>
  98. ,is_interval_set<IntervalSetT> >, bool>::type
  99. contains(const IntervalMapT&, const IntervalSetT&)
  100. {
  101. return true;
  102. }
  103. //------------------------------------------------------------------------------
  104. //- Containedness of sub objects
  105. //------------------------------------------------------------------------------
  106. template<class IntervalMapT>
  107. bool contains(const IntervalMapT& container,
  108. const typename IntervalMapT::element_type& key_value_pair)
  109. {
  110. typename IntervalMapT::const_iterator it_ = container.find(key_value_pair.key);
  111. return it_ != container.end() && (*it_).second == key_value_pair.data;
  112. }
  113. template<class IntervalMapT>
  114. bool contains(const IntervalMapT& container,
  115. const typename IntervalMapT::segment_type sub_segment)
  116. {
  117. typedef typename IntervalMapT::const_iterator const_iterator;
  118. typename IntervalMapT::interval_type sub_interval = sub_segment.first;
  119. if(icl::is_empty(sub_interval))
  120. return true;
  121. std::pair<const_iterator, const_iterator> exterior = container.equal_range(sub_interval);
  122. if(exterior.first == exterior.second)
  123. return false;
  124. const_iterator last_overlap = prior(exterior.second);
  125. if(!(sub_segment.second == exterior.first->second) )
  126. return false;
  127. return
  128. icl::contains(hull(exterior.first->first, last_overlap->first), sub_interval)
  129. && Interval_Map::is_joinable(container, exterior.first, last_overlap);
  130. }
  131. template<class IntervalMapT>
  132. bool contains(const IntervalMapT& super, const IntervalMapT& sub)
  133. {
  134. return Interval_Set::within(sub, super);
  135. }
  136. } // namespace Interval_Map
  137. }} // namespace icl boost
  138. #endif