interval_bounds.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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_BOUNDS_HPP_JOFA_100927
  9. #define BOOST_ICL_CONCEPT_INTERVAL_BOUNDS_HPP_JOFA_100927
  10. #include <boost/icl/interval_bounds.hpp>
  11. #include <boost/icl/type_traits/is_discrete.hpp>
  12. #include <boost/icl/type_traits/is_numeric.hpp>
  13. namespace boost{namespace icl
  14. {
  15. inline interval_bounds left(interval_bounds x1)
  16. { return interval_bounds(x1._bits & interval_bounds::_left); }
  17. inline interval_bounds right(interval_bounds x1)
  18. { return interval_bounds(x1._bits & interval_bounds::_right); }
  19. inline interval_bounds all(interval_bounds x1)
  20. { return interval_bounds(x1._bits & interval_bounds::_all); }
  21. inline bool operator == (const interval_bounds x1, const interval_bounds x2)
  22. { return x1._bits == x2._bits; }
  23. inline bool operator != (const interval_bounds x1, const interval_bounds x2)
  24. { return x1._bits != x2._bits; }
  25. inline interval_bounds operator & (interval_bounds x1, interval_bounds x2)
  26. { return interval_bounds(x1._bits & x2._bits); }
  27. inline interval_bounds operator | (interval_bounds x1, interval_bounds x2)
  28. { return interval_bounds(x1._bits | x2._bits); }
  29. // left shift (multiplies by 2^shift)
  30. inline interval_bounds operator << (interval_bounds bounds, unsigned int shift)
  31. { return interval_bounds(bounds._bits << shift); }
  32. // right shift (divides by 2^shift)
  33. inline interval_bounds operator >> (interval_bounds bounds, unsigned int shift)
  34. { return interval_bounds(bounds._bits >> shift); }
  35. inline interval_bounds operator ~ (interval_bounds x1)
  36. { return all(interval_bounds(~(x1._bits))); }
  37. inline interval_bounds outer_bounds(interval_bounds x1, interval_bounds x2)
  38. { return left(x1) | right(x2); }
  39. inline interval_bounds inner_bounds(interval_bounds x1, interval_bounds x2)
  40. { return interval_bounds(x1.reverse_right() | x2.reverse_left()); }
  41. inline interval_bounds left_bounds(interval_bounds x1, interval_bounds x2)
  42. { return left(x1) | (left(x2) >> 1); }
  43. inline interval_bounds right_bounds(interval_bounds x1, interval_bounds x2)
  44. { return (right(x1) <<1 ) | right(x2); }
  45. inline interval_bounds left_subtract_bounds(interval_bounds x1, interval_bounds x2)
  46. { return right(x1) | ~(right(x2) << 1); }
  47. inline interval_bounds right_subtract_bounds(interval_bounds x1, interval_bounds x2)
  48. { return left(x1) | ~(left(x2) >> 1); }
  49. inline bool is_complementary(interval_bounds x1)
  50. { return x1 == interval_bounds::right_open() || x1 == interval_bounds::left_open(); }
  51. inline bool is_left_closed(interval_bounds bounds)
  52. { return bounds.left().bits()==2; }
  53. inline bool is_right_closed(interval_bounds bounds)
  54. { return bounds.right().bits()==1; }
  55. inline std::string left_bracket(interval_bounds bounds)
  56. { return is_left_closed(bounds) ? "[" : "("; }
  57. inline std::string right_bracket(interval_bounds bounds)
  58. { return is_right_closed(bounds) ? "]" : ")"; }
  59. template <class Type>
  60. inline typename enable_if<is_discrete<Type>, Type>::type
  61. shift_lower(interval_bounds decl, interval_bounds repr, const Type& low)
  62. {
  63. if(is_left_closed(decl) && !is_left_closed(repr))
  64. return icl::pred(low);
  65. else if(!is_left_closed(decl) && is_left_closed(repr))
  66. return icl::succ(low);
  67. else
  68. return low;
  69. }
  70. template <class Type>
  71. inline typename enable_if<is_discrete<Type>, Type>::type
  72. shift_upper(interval_bounds decl, interval_bounds repr, const Type& up)
  73. {
  74. if(!is_right_closed(decl) && is_right_closed(repr))
  75. return icl::pred(up);
  76. else if(is_right_closed(decl) && !is_right_closed(repr))
  77. return icl::succ(up);
  78. else
  79. return up;
  80. }
  81. template<class CharType, class CharTraits>
  82. std::basic_ostream<CharType, CharTraits>& operator <<
  83. (std::basic_ostream<CharType, CharTraits> &stream,
  84. interval_bounds const& object)
  85. {
  86. return stream << left_bracket(object) << right_bracket(object);
  87. }
  88. template<class IntervalT>
  89. inline typename
  90. boost::enable_if<has_dynamic_bounds<IntervalT>, interval_bounds>::type
  91. outer_bounds(const IntervalT& x1, const IntervalT& x2)
  92. { return outer_bounds(x1.bounds(), x2.bounds()); }
  93. template<class IntervalT>
  94. inline typename
  95. boost::enable_if<has_dynamic_bounds<IntervalT>, interval_bounds>::type
  96. inner_bounds(const IntervalT& x1, const IntervalT& x2)
  97. { return inner_bounds(x1.bounds(), x2.bounds()); }
  98. template<class IntervalT>
  99. inline typename
  100. boost::enable_if<has_dynamic_bounds<IntervalT>, interval_bounds>::type
  101. left_bounds(const IntervalT& x1, const IntervalT& x2)
  102. { return left_bounds(x1.bounds(), x2.bounds()); }
  103. template<class IntervalT>
  104. inline typename
  105. boost::enable_if<has_dynamic_bounds<IntervalT>, interval_bounds>::type
  106. right_bounds(const IntervalT& x1, const IntervalT& x2)
  107. { return right_bounds(x1.bounds(), x2.bounds()); }
  108. template<class IntervalT>
  109. inline typename
  110. boost::enable_if<has_dynamic_bounds<IntervalT>, interval_bounds>::type
  111. left_subtract_bounds(const IntervalT& x1, const IntervalT& x2)
  112. { return left_subtract_bounds(x1.bounds(), x2.bounds()); }
  113. template<class IntervalT>
  114. inline typename
  115. boost::enable_if<has_dynamic_bounds<IntervalT>, interval_bounds>::type
  116. right_subtract_bounds(const IntervalT& x1, const IntervalT& x2)
  117. { return right_subtract_bounds(x1.bounds(), x2.bounds()); }
  118. }} // namespace icl boost
  119. #endif