interval_associator_base.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*-----------------------------------------------------------------------------+
  2. Copyright (c) 2011-2011: 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_BASE_HPP_JOFA_110301
  9. #define BOOST_ICL_CONCEPT_INTERVAL_ASSOCIATOR_BASE_HPP_JOFA_110301
  10. #include <boost/icl/type_traits/domain_type_of.hpp>
  11. #include <boost/icl/type_traits/interval_type_of.hpp>
  12. #include <boost/icl/type_traits/is_combinable.hpp>
  13. #include <boost/icl/concept/set_value.hpp>
  14. #include <boost/icl/concept/map_value.hpp>
  15. #include <boost/icl/concept/interval.hpp>
  16. namespace boost{ namespace icl
  17. {
  18. //==============================================================================
  19. //= Selection<IntervalSet|IntervalMap>
  20. //==============================================================================
  21. template<class Type> inline
  22. typename enable_if<mpl::and_< is_interval_container<Type>
  23. , is_discrete<typename domain_type_of<Type>::type>
  24. >
  25. , typename Type::const_iterator>::type
  26. find(const Type& object, const typename domain_type_of<Type>::type& key_val)
  27. {
  28. //CL typedef typename Type::const_iterator const_iterator;
  29. typedef typename Type::interval_type interval_type;
  30. return object.find(icl::detail::unit_trail<interval_type>(key_val));
  31. }
  32. template<class Type> inline
  33. typename enable_if<mpl::and_< is_interval_container<Type>
  34. , is_continuous<typename domain_type_of<Type>::type>
  35. , has_dynamic_bounds<typename interval_type_of<Type>::type>
  36. >
  37. , typename Type::const_iterator>::type
  38. find(const Type& object, const typename domain_type_of<Type>::type& key_val)
  39. {
  40. //CL typedef typename Type::const_iterator const_iterator;
  41. typedef typename Type::interval_type interval_type;
  42. return object.find(icl::singleton<interval_type>(key_val));
  43. }
  44. template<class Type> inline
  45. typename enable_if<mpl::and_< is_interval_container<Type>
  46. , is_continuous<typename domain_type_of<Type>::type>
  47. , is_static_right_open<typename interval_type_of<Type>::type>
  48. , boost::detail::is_incrementable<typename domain_type_of<Type>::type>
  49. >
  50. , typename Type::const_iterator>::type
  51. find(const Type& object, const typename domain_type_of<Type>::type& key_val)
  52. {
  53. typedef typename Type::const_iterator const_iterator;
  54. typedef typename Type::interval_type interval_type;
  55. const_iterator first_collision = object.lower_bound(icl::detail::unit_trail<interval_type>(key_val));
  56. // A part of the unit_trail(key_value)-interval may be found in the container, that
  57. // does not contain key_value. Therefore we have to check for its existence:
  58. return ( first_collision == object.end()
  59. || icl::contains(key_value<Type>(first_collision), key_val) )
  60. ? first_collision
  61. : object.end();
  62. }
  63. template<class Type> inline
  64. typename enable_if<mpl::and_< is_interval_container<Type>
  65. , is_continuous<typename domain_type_of<Type>::type>
  66. , is_static_left_open<typename interval_type_of<Type>::type>
  67. , boost::detail::is_incrementable<typename domain_type_of<Type>::type>
  68. >
  69. , typename Type::const_iterator>::type
  70. find(const Type& object, const typename domain_type_of<Type>::type& key_val)
  71. {
  72. typedef typename Type::const_iterator const_iterator;
  73. typedef typename Type::interval_type interval_type;
  74. const_iterator last_collision = object.upper_bound(icl::detail::unit_trail<interval_type>(key_val));
  75. if(last_collision != object.begin())
  76. --last_collision;
  77. // A part of the unit_trail(key_value)-interval may be found in the container, that
  78. // does not contain key_value. Therefore we have to check for its existence:
  79. return ( last_collision == object.end()
  80. || icl::contains(key_value<Type>(last_collision), key_val) )
  81. ? last_collision
  82. : object.end();
  83. }
  84. // NOTE: find(object, key) won't compile if key is of continuous type that does
  85. // not implement in(de)crementation (e.g. std::string).
  86. template<class Type> inline
  87. typename enable_if< is_interval_container<Type>
  88. , typename Type::const_iterator>::type
  89. find(const Type& object, const typename interval_type_of<Type>::type& inter_val)
  90. {
  91. return object.find(inter_val);
  92. }
  93. //==============================================================================
  94. //= Morphisms
  95. //==============================================================================
  96. template<class Type>
  97. typename enable_if<is_interval_container<Type>, Type>::type&
  98. join(Type& object)
  99. {
  100. typedef typename Type::interval_type interval_type;
  101. typedef typename Type::iterator iterator;
  102. iterator it_ = object.begin();
  103. if(it_ == object.end())
  104. return object;
  105. iterator next_ = it_; next_++;
  106. while(next_ != object.end())
  107. {
  108. if( segmental::is_joinable<Type>(it_, next_) )
  109. {
  110. iterator fst_mem = it_; // hold the first member
  111. // Go on while touching members are found
  112. it_++; next_++;
  113. while( next_ != object.end()
  114. && segmental::is_joinable<Type>(it_, next_) )
  115. { it_++; next_++; }
  116. // finally we arrive at the end of a sequence of joinable intervals
  117. // and it points to the last member of that sequence
  118. const_cast<interval_type&>(key_value<Type>(it_))
  119. = hull(key_value<Type>(it_), key_value<Type>(fst_mem));
  120. object.erase(fst_mem, it_);
  121. it_++; next_=it_;
  122. if(next_!=object.end())
  123. next_++;
  124. }
  125. else { it_++; next_++; }
  126. }
  127. return object;
  128. }
  129. }} // namespace boost icl
  130. #endif