iter_find.hpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. // Boost string_algo library iter_find.hpp header file ---------------------------//
  2. // Copyright Pavol Droba 2002-2003.
  3. //
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. // See http://www.boost.org/ for updates, documentation, and revision history.
  8. #ifndef BOOST_STRING_ITER_FIND_HPP
  9. #define BOOST_STRING_ITER_FIND_HPP
  10. #include <boost/algorithm/string/config.hpp>
  11. #include <algorithm>
  12. #include <iterator>
  13. #include <boost/iterator/transform_iterator.hpp>
  14. #include <boost/range/iterator_range_core.hpp>
  15. #include <boost/range/begin.hpp>
  16. #include <boost/range/end.hpp>
  17. #include <boost/range/iterator.hpp>
  18. #include <boost/range/value_type.hpp>
  19. #include <boost/range/as_literal.hpp>
  20. #include <boost/algorithm/string/concept.hpp>
  21. #include <boost/algorithm/string/find_iterator.hpp>
  22. #include <boost/algorithm/string/detail/util.hpp>
  23. /*! \file
  24. Defines generic split algorithms. Split algorithms can be
  25. used to divide a sequence into several part according
  26. to a given criteria. Result is given as a 'container
  27. of containers' where elements are copies or references
  28. to extracted parts.
  29. There are two algorithms provided. One iterates over matching
  30. substrings, the other one over the gaps between these matches.
  31. */
  32. namespace boost {
  33. namespace algorithm {
  34. // iterate find ---------------------------------------------------//
  35. //! Iter find algorithm
  36. /*!
  37. This algorithm executes a given finder in iteration on the input,
  38. until the end of input is reached, or no match is found.
  39. Iteration is done using built-in find_iterator, so the real
  40. searching is performed only when needed.
  41. In each iteration new match is found and added to the result.
  42. \param Result A 'container container' to contain the result of search.
  43. Both outer and inner container must have constructor taking a pair
  44. of iterators as an argument.
  45. Typical type of the result is
  46. \c std::vector<boost::iterator_range<iterator>>
  47. (each element of such a vector will container a range delimiting
  48. a match).
  49. \param Input A container which will be searched.
  50. \param Finder A Finder object used for searching
  51. \return A reference to the result
  52. \note Prior content of the result will be overwritten.
  53. */
  54. template<
  55. typename SequenceSequenceT,
  56. typename RangeT,
  57. typename FinderT >
  58. inline SequenceSequenceT&
  59. iter_find(
  60. SequenceSequenceT& Result,
  61. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  62. RangeT&& Input,
  63. #else
  64. RangeT& Input,
  65. #endif
  66. FinderT Finder )
  67. {
  68. BOOST_CONCEPT_ASSERT((
  69. FinderConcept<
  70. FinderT,
  71. BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
  72. ));
  73. iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
  74. typedef BOOST_STRING_TYPENAME
  75. range_iterator<RangeT>::type input_iterator_type;
  76. typedef find_iterator<input_iterator_type> find_iterator_type;
  77. typedef detail::copy_iterator_rangeF<
  78. BOOST_STRING_TYPENAME
  79. range_value<SequenceSequenceT>::type,
  80. input_iterator_type> copy_range_type;
  81. input_iterator_type InputEnd=::boost::end(lit_input);
  82. typedef transform_iterator<copy_range_type, find_iterator_type>
  83. transform_iter_type;
  84. transform_iter_type itBegin=
  85. ::boost::make_transform_iterator(
  86. find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ),
  87. copy_range_type());
  88. transform_iter_type itEnd=
  89. ::boost::make_transform_iterator(
  90. find_iterator_type(),
  91. copy_range_type());
  92. SequenceSequenceT Tmp(itBegin, itEnd);
  93. Result.swap(Tmp);
  94. return Result;
  95. }
  96. // iterate split ---------------------------------------------------//
  97. //! Split find algorithm
  98. /*!
  99. This algorithm executes a given finder in iteration on the input,
  100. until the end of input is reached, or no match is found.
  101. Iteration is done using built-in find_iterator, so the real
  102. searching is performed only when needed.
  103. Each match is used as a separator of segments. These segments are then
  104. returned in the result.
  105. \param Result A 'container container' to contain the result of search.
  106. Both outer and inner container must have constructor taking a pair
  107. of iterators as an argument.
  108. Typical type of the result is
  109. \c std::vector<boost::iterator_range<iterator>>
  110. (each element of such a vector will container a range delimiting
  111. a match).
  112. \param Input A container which will be searched.
  113. \param Finder A finder object used for searching
  114. \return A reference to the result
  115. \note Prior content of the result will be overwritten.
  116. */
  117. template<
  118. typename SequenceSequenceT,
  119. typename RangeT,
  120. typename FinderT >
  121. inline SequenceSequenceT&
  122. iter_split(
  123. SequenceSequenceT& Result,
  124. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  125. RangeT&& Input,
  126. #else
  127. RangeT& Input,
  128. #endif
  129. FinderT Finder )
  130. {
  131. BOOST_CONCEPT_ASSERT((
  132. FinderConcept<FinderT,
  133. BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
  134. ));
  135. iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
  136. typedef BOOST_STRING_TYPENAME
  137. range_iterator<RangeT>::type input_iterator_type;
  138. typedef split_iterator<input_iterator_type> find_iterator_type;
  139. typedef detail::copy_iterator_rangeF<
  140. BOOST_STRING_TYPENAME
  141. range_value<SequenceSequenceT>::type,
  142. input_iterator_type> copy_range_type;
  143. input_iterator_type InputEnd=::boost::end(lit_input);
  144. typedef transform_iterator<copy_range_type, find_iterator_type>
  145. transform_iter_type;
  146. transform_iter_type itBegin=
  147. ::boost::make_transform_iterator(
  148. find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ),
  149. copy_range_type() );
  150. transform_iter_type itEnd=
  151. ::boost::make_transform_iterator(
  152. find_iterator_type(),
  153. copy_range_type() );
  154. SequenceSequenceT Tmp(itBegin, itEnd);
  155. Result.swap(Tmp);
  156. return Result;
  157. }
  158. } // namespace algorithm
  159. // pull names to the boost namespace
  160. using algorithm::iter_find;
  161. using algorithm::iter_split;
  162. } // namespace boost
  163. #endif // BOOST_STRING_ITER_FIND_HPP