range_run.ipp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*=============================================================================
  2. Copyright (c) 2001-2003 Joel de Guzman
  3. http://spirit.sourceforge.net/
  4. Use, modification and distribution is subject to the Boost Software
  5. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. #ifndef BOOST_XPRESSIVE_SPIRIT_RANGE_RUN_IPP
  9. #define BOOST_XPRESSIVE_SPIRIT_RANGE_RUN_IPP
  10. ///////////////////////////////////////////////////////////////////////////////
  11. #include <algorithm> // for std::lower_bound
  12. #include <boost/limits.hpp>
  13. #include <boost/assert.hpp>
  14. #include <boost/xpressive/detail/utility/chset/range_run.hpp>
  15. ///////////////////////////////////////////////////////////////////////////////
  16. namespace boost { namespace xpressive { namespace detail
  17. {
  18. ///////////////////////////////////////////////////////////////////////
  19. //
  20. // range class implementation
  21. //
  22. ///////////////////////////////////////////////////////////////////////
  23. template<typename Char>
  24. inline range<Char>::range(Char first, Char last)
  25. : first_(first)
  26. , last_(last)
  27. {
  28. }
  29. //////////////////////////////////
  30. template<typename Char>
  31. inline bool range<Char>::is_valid() const
  32. {
  33. return this->first_ <= this->last_;
  34. }
  35. //////////////////////////////////
  36. template<typename Char>
  37. inline bool range<Char>::includes(range<Char> const &r) const
  38. {
  39. return (this->first_ <= r.first_) && (this->last_ >= r.last_);
  40. }
  41. //////////////////////////////////
  42. template<typename Char>
  43. inline bool range<Char>::includes(Char v) const
  44. {
  45. return (this->first_ <= v) && (this->last_ >= v);
  46. }
  47. //////////////////////////////////
  48. template<typename Char>
  49. inline bool range<Char>::overlaps(range<Char> const &r) const
  50. {
  51. Char decr_first = (std::min)(this->first_, Char(this->first_-1));
  52. Char incr_last = (std::max)(this->last_, Char(this->last_+1));
  53. return (decr_first <= r.last_) && (incr_last >= r.first_);
  54. }
  55. //////////////////////////////////
  56. template<typename Char>
  57. inline void range<Char>::merge(range<Char> const &r)
  58. {
  59. this->first_ = (std::min)(this->first_, r.first_);
  60. this->last_ = (std::max)(this->last_, r.last_);
  61. }
  62. ///////////////////////////////////////////////////////////////////////
  63. //
  64. // range_run class implementation
  65. //
  66. ///////////////////////////////////////////////////////////////////////
  67. template<typename Char>
  68. inline bool range_run<Char>::empty() const
  69. {
  70. return this->run_.empty();
  71. }
  72. template<typename Char>
  73. inline bool range_run<Char>::test(Char v) const
  74. {
  75. if(this->run_.empty())
  76. {
  77. return false;
  78. }
  79. const_iterator iter = std::lower_bound(
  80. this->run_.begin()
  81. , this->run_.end()
  82. , range<Char>(v, v)
  83. , range_compare<Char>()
  84. );
  85. return (iter != this->run_.end() && iter->includes(v))
  86. || (iter != this->run_.begin() && (--iter)->includes(v));
  87. }
  88. template<typename Char>
  89. template<typename Traits>
  90. inline bool range_run<Char>::test(Char v, Traits const &tr) const
  91. {
  92. const_iterator begin = this->run_.begin();
  93. const_iterator end = this->run_.end();
  94. for(; begin != end; ++begin)
  95. {
  96. if(tr.in_range_nocase(begin->first_, begin->last_, v))
  97. {
  98. return true;
  99. }
  100. }
  101. return false;
  102. }
  103. //////////////////////////////////
  104. template<typename Char>
  105. inline void range_run<Char>::swap(range_run<Char> &rr)
  106. {
  107. this->run_.swap(rr.run_);
  108. }
  109. //////////////////////////////////
  110. template<typename Char>
  111. void range_run<Char>::merge(iterator iter, range<Char> const &r)
  112. {
  113. BOOST_ASSERT(iter != this->run_.end());
  114. iter->merge(r);
  115. iterator i = iter;
  116. while(++i != this->run_.end() && iter->overlaps(*i))
  117. {
  118. iter->merge(*i);
  119. }
  120. this->run_.erase(++iter, i);
  121. }
  122. //////////////////////////////////
  123. template<typename Char>
  124. void range_run<Char>::set(range<Char> const &r)
  125. {
  126. BOOST_ASSERT(r.is_valid());
  127. if(!this->run_.empty())
  128. {
  129. iterator iter = std::lower_bound(this->run_.begin(), this->run_.end(), r, range_compare<Char>());
  130. if((iter != this->run_.end() && iter->includes(r)) ||
  131. (iter != this->run_.begin() && (iter - 1)->includes(r)))
  132. {
  133. return;
  134. }
  135. else if(iter != this->run_.begin() && (iter - 1)->overlaps(r))
  136. {
  137. this->merge(--iter, r);
  138. }
  139. else if(iter != this->run_.end() && iter->overlaps(r))
  140. {
  141. this->merge(iter, r);
  142. }
  143. else
  144. {
  145. this->run_.insert(iter, r);
  146. }
  147. }
  148. else
  149. {
  150. this->run_.push_back(r);
  151. }
  152. }
  153. //////////////////////////////////
  154. template<typename Char>
  155. void range_run<Char>::clear(range<Char> const &r)
  156. {
  157. BOOST_ASSERT(r.is_valid());
  158. if(!this->run_.empty())
  159. {
  160. iterator iter = std::lower_bound(this->run_.begin(), this->run_.end(), r, range_compare<Char>());
  161. iterator left_iter;
  162. if((iter != this->run_.begin()) &&
  163. (left_iter = (iter - 1))->includes(r.first_))
  164. {
  165. if(left_iter->last_ > r.last_)
  166. {
  167. Char save_last = left_iter->last_;
  168. left_iter->last_ = r.first_-1;
  169. this->run_.insert(iter, range<Char>(r.last_+1, save_last));
  170. return;
  171. }
  172. else
  173. {
  174. left_iter->last_ = r.first_-1;
  175. }
  176. }
  177. iterator i = iter;
  178. for(; i != this->run_.end() && r.includes(*i); ++i) {}
  179. if(i != this->run_.end() && i->includes(r.last_))
  180. {
  181. i->first_ = r.last_+1;
  182. }
  183. this->run_.erase(iter, i);
  184. }
  185. }
  186. //////////////////////////////////
  187. template<typename Char>
  188. inline void range_run<Char>::clear()
  189. {
  190. this->run_.clear();
  191. }
  192. //////////////////////////////////
  193. template<typename Char>
  194. inline typename range_run<Char>::const_iterator range_run<Char>::begin() const
  195. {
  196. return this->run_.begin();
  197. }
  198. //////////////////////////////////
  199. template<typename Char>
  200. inline typename range_run<Char>::const_iterator range_run<Char>::end() const
  201. {
  202. return this->run_.end();
  203. }
  204. }}} // namespace boost::xpressive::detail
  205. #endif