1 | // Boost string_algo library iter_find.hpp header file ---------------------------// |
---|---|

2 | |

3 | // Copyright Pavol Droba 2002-2003. |

4 | // |

5 | // Distributed under the Boost Software License, Version 1.0. |

6 | // (See accompanying file LICENSE_1_0.txt or copy at |

7 | // http://www.boost.org/LICENSE_1_0.txt) |

8 | |

9 | // See http://www.boost.org/ for updates, documentation, and revision history. |

10 | |

11 | #ifndef BOOST_STRING_ITER_FIND_HPP |

12 | #define BOOST_STRING_ITER_FIND_HPP |

13 | |

14 | #include <boost/algorithm/string/config.hpp> |

15 | #include <algorithm> |

16 | #include <iterator> |

17 | #include <boost/iterator/transform_iterator.hpp> |

18 | |

19 | #include <boost/range/iterator_range_core.hpp> |

20 | #include <boost/range/begin.hpp> |

21 | #include <boost/range/end.hpp> |

22 | #include <boost/range/iterator.hpp> |

23 | #include <boost/range/value_type.hpp> |

24 | #include <boost/range/as_literal.hpp> |

25 | |

26 | #include <boost/algorithm/string/concept.hpp> |

27 | #include <boost/algorithm/string/find_iterator.hpp> |

28 | #include <boost/algorithm/string/detail/util.hpp> |

29 | |

30 | /*! \file |

31 | Defines generic split algorithms. Split algorithms can be |

32 | used to divide a sequence into several part according |

33 | to a given criteria. Result is given as a 'container |

34 | of containers' where elements are copies or references |

35 | to extracted parts. |

36 | |

37 | There are two algorithms provided. One iterates over matching |

38 | substrings, the other one over the gaps between these matches. |

39 | */ |

40 | |

41 | namespace boost { |

42 | namespace algorithm { |

43 | |

44 | // iterate find ---------------------------------------------------// |

45 | |

46 | //! Iter find algorithm |

47 | /*! |

48 | This algorithm executes a given finder in iteration on the input, |

49 | until the end of input is reached, or no match is found. |

50 | Iteration is done using built-in find_iterator, so the real |

51 | searching is performed only when needed. |

52 | In each iteration new match is found and added to the result. |

53 | |

54 | \param Result A 'container container' to contain the result of search. |

55 | Both outer and inner container must have constructor taking a pair |

56 | of iterators as an argument. |

57 | Typical type of the result is |

58 | \c std::vector<boost::iterator_range<iterator>> |

59 | (each element of such a vector will container a range delimiting |

60 | a match). |

61 | \param Input A container which will be searched. |

62 | \param Finder A Finder object used for searching |

63 | \return A reference to the result |

64 | |

65 | \note Prior content of the result will be overwritten. |

66 | */ |

67 | template< |

68 | typename SequenceSequenceT, |

69 | typename RangeT, |

70 | typename FinderT > |

71 | inline SequenceSequenceT& |

72 | iter_find( |

73 | SequenceSequenceT& Result, |

74 | RangeT& Input, |

75 | FinderT Finder ) |

76 | { |

77 | BOOST_CONCEPT_ASSERT(( |

78 | FinderConcept< |

79 | FinderT, |

80 | BOOST_STRING_TYPENAME range_iterator<RangeT>::type> |

81 | )); |

82 | |

83 | iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input)); |

84 | |

85 | typedef BOOST_STRING_TYPENAME |

86 | range_iterator<RangeT>::type input_iterator_type; |

87 | typedef find_iterator<input_iterator_type> find_iterator_type; |

88 | typedef detail::copy_iterator_rangeF< |

89 | BOOST_STRING_TYPENAME |

90 | range_value<SequenceSequenceT>::type, |

91 | input_iterator_type> copy_range_type; |

92 | |

93 | input_iterator_type InputEnd=::boost::end(lit_input); |

94 | |

95 | typedef transform_iterator<copy_range_type, find_iterator_type> |

96 | transform_iter_type; |

97 | |

98 | transform_iter_type itBegin= |

99 | ::boost::make_transform_iterator( |

100 | find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ), |

101 | copy_range_type()); |

102 | |

103 | transform_iter_type itEnd= |

104 | ::boost::make_transform_iterator( |

105 | find_iterator_type(), |

106 | copy_range_type()); |

107 | |

108 | SequenceSequenceT Tmp(itBegin, itEnd); |

109 | |

110 | Result.swap(Tmp); |

111 | return Result; |

112 | } |

113 | |

114 | // iterate split ---------------------------------------------------// |

115 | |

116 | //! Split find algorithm |

117 | /*! |

118 | This algorithm executes a given finder in iteration on the input, |

119 | until the end of input is reached, or no match is found. |

120 | Iteration is done using built-in find_iterator, so the real |

121 | searching is performed only when needed. |

122 | Each match is used as a separator of segments. These segments are then |

123 | returned in the result. |

124 | |

125 | \param Result A 'container container' to contain the result of search. |

126 | Both outer and inner container must have constructor taking a pair |

127 | of iterators as an argument. |

128 | Typical type of the result is |

129 | \c std::vector<boost::iterator_range<iterator>> |

130 | (each element of such a vector will container a range delimiting |

131 | a match). |

132 | \param Input A container which will be searched. |

133 | \param Finder A finder object used for searching |

134 | \return A reference to the result |

135 | |

136 | \note Prior content of the result will be overwritten. |

137 | */ |

138 | template< |

139 | typename SequenceSequenceT, |

140 | typename RangeT, |

141 | typename FinderT > |

142 | inline SequenceSequenceT& |

143 | iter_split( |

144 | SequenceSequenceT& Result, |

145 | RangeT& Input, |

146 | FinderT Finder ) |

147 | { |

148 | BOOST_CONCEPT_ASSERT(( |

149 | FinderConcept<FinderT, |

150 | BOOST_STRING_TYPENAME range_iterator<RangeT>::type> |

151 | )); |

152 | |

153 | iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input)); |

154 | |

155 | typedef BOOST_STRING_TYPENAME |

156 | range_iterator<RangeT>::type input_iterator_type; |

157 | typedef split_iterator<input_iterator_type> find_iterator_type; |

158 | typedef detail::copy_iterator_rangeF< |

159 | BOOST_STRING_TYPENAME |

160 | range_value<SequenceSequenceT>::type, |

161 | input_iterator_type> copy_range_type; |

162 | |

163 | input_iterator_type InputEnd=::boost::end(lit_input); |

164 | |

165 | typedef transform_iterator<copy_range_type, find_iterator_type> |

166 | transform_iter_type; |

167 | |

168 | transform_iter_type itBegin= |

169 | ::boost::make_transform_iterator( |

170 | find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ), |

171 | copy_range_type() ); |

172 | |

173 | transform_iter_type itEnd= |

174 | ::boost::make_transform_iterator( |

175 | find_iterator_type(), |

176 | copy_range_type() ); |

177 | |

178 | SequenceSequenceT Tmp(itBegin, itEnd); |

179 | |

180 | Result.swap(Tmp); |

181 | return Result; |

182 | } |

183 | |

184 | } // namespace algorithm |

185 | |

186 | // pull names to the boost namespace |

187 | using algorithm::iter_find; |

188 | using algorithm::iter_split; |

189 | |

190 | } // namespace boost |

191 | |

192 | |

193 | #endif // BOOST_STRING_ITER_FIND_HPP |

194 |