algorithm.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // algorithm.hpp
  3. //
  4. // Copyright 2008 Eric Niebler. Distributed under the Boost
  5. // Software License, Version 1.0. (See accompanying file
  6. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. #ifndef BOOST_XPRESSIVE_DETAIL_UTILITY_ALGORITHM_HPP_EAN_10_04_2005
  8. #define BOOST_XPRESSIVE_DETAIL_UTILITY_ALGORITHM_HPP_EAN_10_04_2005
  9. // MS compatible compilers support #pragma once
  10. #if defined(_MSC_VER)
  11. # pragma once
  12. #endif
  13. #include <string>
  14. #include <climits>
  15. #include <algorithm>
  16. #include <boost/version.hpp>
  17. #include <boost/range/end.hpp>
  18. #include <boost/range/begin.hpp>
  19. #include <boost/range/size.hpp>
  20. #include <boost/range/value_type.hpp>
  21. #include <boost/type_traits/remove_const.hpp>
  22. #include <boost/iterator/iterator_traits.hpp>
  23. #include <boost/xpressive/detail/utility/ignore_unused.hpp>
  24. namespace boost { namespace xpressive { namespace detail
  25. {
  26. ///////////////////////////////////////////////////////////////////////////////
  27. // any
  28. //
  29. template<typename InIter, typename Pred>
  30. inline bool any(InIter begin, InIter end, Pred pred)
  31. {
  32. return end != std::find_if(begin, end, pred);
  33. }
  34. ///////////////////////////////////////////////////////////////////////////////
  35. // find_nth_if
  36. //
  37. template<typename FwdIter, typename Diff, typename Pred>
  38. FwdIter find_nth_if(FwdIter begin, FwdIter end, Diff count, Pred pred)
  39. {
  40. for(; begin != end; ++begin)
  41. {
  42. if(pred(*begin) && 0 == count--)
  43. {
  44. return begin;
  45. }
  46. }
  47. return end;
  48. }
  49. ///////////////////////////////////////////////////////////////////////////////
  50. // toi
  51. //
  52. template<typename InIter, typename Traits>
  53. int toi(InIter &begin, InIter end, Traits const &tr, int radix = 10, int max = INT_MAX)
  54. {
  55. detail::ignore_unused(tr);
  56. int i = 0, c = 0;
  57. for(; begin != end && -1 != (c = tr.value(*begin, radix)); ++begin)
  58. {
  59. if(max < ((i *= radix) += c))
  60. return i / radix;
  61. }
  62. return i;
  63. }
  64. ///////////////////////////////////////////////////////////////////////////////
  65. // advance_to
  66. //
  67. template<typename BidiIter, typename Diff>
  68. inline bool advance_to_impl(BidiIter & iter, Diff diff, BidiIter end, std::bidirectional_iterator_tag)
  69. {
  70. for(; 0 < diff && iter != end; --diff)
  71. ++iter;
  72. for(; 0 > diff && iter != end; ++diff)
  73. --iter;
  74. return 0 == diff;
  75. }
  76. template<typename RandIter, typename Diff>
  77. inline bool advance_to_impl(RandIter & iter, Diff diff, RandIter end, std::random_access_iterator_tag)
  78. {
  79. if(0 < diff)
  80. {
  81. if((end - iter) < diff)
  82. return false;
  83. }
  84. else if(0 > diff)
  85. {
  86. if((iter - end) < -diff)
  87. return false;
  88. }
  89. iter += diff;
  90. return true;
  91. }
  92. template<typename Iter, typename Diff>
  93. inline bool advance_to(Iter & iter, Diff diff, Iter end)
  94. {
  95. return detail::advance_to_impl(iter, diff, end, typename iterator_category<Iter>::type());
  96. }
  97. ///////////////////////////////////////////////////////////////////////////////
  98. // range_data
  99. //
  100. template<typename T>
  101. struct range_data
  102. : range_value<T>
  103. {};
  104. template<typename T>
  105. struct range_data<T *>
  106. : remove_const<T>
  107. {};
  108. template<typename T> std::ptrdiff_t is_null_terminated(T const &) { return 0; }
  109. #if BOOST_VERSION >= 103500
  110. inline std::ptrdiff_t is_null_terminated(char const *) { return 1; }
  111. #ifndef BOOST_XPRESSIVE_NO_WREGEX
  112. inline std::ptrdiff_t is_null_terminated(wchar_t const *) { return 1; }
  113. #endif
  114. #endif
  115. ///////////////////////////////////////////////////////////////////////////////
  116. // data_begin/data_end
  117. //
  118. template<typename Cont>
  119. typename range_data<Cont>::type const *data_begin(Cont const &cont)
  120. {
  121. return &*boost::begin(cont);
  122. }
  123. template<typename Cont>
  124. typename range_data<Cont>::type const *data_end(Cont const &cont)
  125. {
  126. return &*boost::begin(cont) + boost::size(cont) - is_null_terminated(cont);
  127. }
  128. template<typename Char, typename Traits, typename Alloc>
  129. Char const *data_begin(std::basic_string<Char, Traits, Alloc> const &str)
  130. {
  131. return str.data();
  132. }
  133. template<typename Char, typename Traits, typename Alloc>
  134. Char const *data_end(std::basic_string<Char, Traits, Alloc> const &str)
  135. {
  136. return str.data() + str.size();
  137. }
  138. template<typename Char>
  139. Char const *data_begin(Char const *const &sz)
  140. {
  141. return sz;
  142. }
  143. template<typename Char>
  144. Char const *data_end(Char const *const &sz)
  145. {
  146. Char const *tmp = sz;
  147. for(; *tmp; ++tmp)
  148. ;
  149. return tmp;
  150. }
  151. }}}
  152. #endif