1// Boost string_algo library find_iterator.hpp header file ---------------------------//
2
3// Copyright Pavol Droba 2002-2004.
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_FIND_ITERATOR_HPP
12#define BOOST_STRING_FIND_ITERATOR_HPP
13
14#include <boost/algorithm/string/config.hpp>
15#include <boost/iterator/iterator_facade.hpp>
16#include <boost/iterator/iterator_categories.hpp>
17
18#include <boost/range/iterator_range_core.hpp>
19#include <boost/range/begin.hpp>
20#include <boost/range/end.hpp>
21#include <boost/range/iterator.hpp>
22#include <boost/range/as_literal.hpp>
23
24#include <boost/algorithm/string/detail/find_iterator.hpp>
25
26/*! \file
27 Defines find iterator classes. Find iterator repeatedly applies a Finder
28 to the specified input string to search for matches. Dereferencing
29 the iterator yields the current match or a range between the last and the current
30 match depending on the iterator used.
31*/
32
33namespace boost {
34 namespace algorithm {
35
36// find_iterator -----------------------------------------------//
37
38 //! find_iterator
39 /*!
40 Find iterator encapsulates a Finder and allows
41 for incremental searching in a string.
42 Each increment moves the iterator to the next match.
43
44 Find iterator is a readable forward traversal iterator.
45
46 Dereferencing the iterator yields an iterator_range delimiting
47 the current match.
48 */
49 template<typename IteratorT>
50 class find_iterator :
51 public iterator_facade<
52 find_iterator<IteratorT>,
53 const iterator_range<IteratorT>,
54 forward_traversal_tag >,
55 private detail::find_iterator_base<IteratorT>
56 {
57 private:
58 // facade support
59 friend class ::boost::iterator_core_access;
60
61 private:
62 // typedefs
63
64 typedef detail::find_iterator_base<IteratorT> base_type;
65 typedef BOOST_STRING_TYPENAME
66 base_type::input_iterator_type input_iterator_type;
67 typedef BOOST_STRING_TYPENAME
68 base_type::match_type match_type;
69
70 public:
71 //! Default constructor
72 /*!
73 Construct null iterator. All null iterators are equal.
74
75 \post eof()==true
76 */
77 find_iterator() {}
78
79 //! Copy constructor
80 /*!
81 Construct a copy of the find_iterator
82 */
83 find_iterator( const find_iterator& Other ) :
84 base_type(Other),
85 m_Match(Other.m_Match),
86 m_End(Other.m_End) {}
87
88 //! Constructor
89 /*!
90 Construct new find_iterator for a given finder
91 and a range.
92 */
93 template<typename FinderT>
94 find_iterator(
95 IteratorT Begin,
96 IteratorT End,
97 FinderT Finder ) :
98 detail::find_iterator_base<IteratorT>(Finder,0),
99 m_Match(Begin,Begin),
100 m_End(End)
101 {
102 increment();
103 }
104
105 //! Constructor
106 /*!
107 Construct new find_iterator for a given finder
108 and a range.
109 */
110 template<typename FinderT, typename RangeT>
111 find_iterator(
112 RangeT& Col,
113 FinderT Finder ) :
114 detail::find_iterator_base<IteratorT>(Finder,0)
115 {
116 iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
117 m_Match=::boost::make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
118 m_End=::boost::end(lit_col);
119
120 increment();
121 }
122
123 private:
124 // iterator operations
125
126 // dereference
127 const match_type& dereference() const
128 {
129 return m_Match;
130 }
131
132 // increment
133 void increment()
134 {
135 m_Match=this->do_find(m_Match.end(),m_End);
136 }
137
138 // comparison
139 bool equal( const find_iterator& Other ) const
140 {
141 bool bEof=eof();
142 bool bOtherEof=Other.eof();
143
144 return bEof || bOtherEof ? bEof==bOtherEof :
145 (
146 m_Match==Other.m_Match &&
147 m_End==Other.m_End
148 );
149 }
150
151 public:
152 // operations
153
154 //! Eof check
155 /*!
156 Check the eof condition. Eof condition means that
157 there is nothing more to be searched i.e. find_iterator
158 is after the last match.
159 */
160 bool eof() const
161 {
162 return
163 this->is_null() ||
164 (
165 m_Match.begin() == m_End &&
166 m_Match.end() == m_End
167 );
168 }
169
170 private:
171 // Attributes
172 match_type m_Match;
173 input_iterator_type m_End;
174 };
175
176 //! find iterator construction helper
177 /*!
178 * Construct a find iterator to iterate through the specified string
179 */
180 template<typename RangeT, typename FinderT>
181 inline find_iterator<
182 BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
183 make_find_iterator(
184 RangeT& Collection,
185 FinderT Finder)
186 {
187 return find_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
188 Collection, Finder);
189 }
190
191// split iterator -----------------------------------------------//
192
193 //! split_iterator
194 /*!
195 Split iterator encapsulates a Finder and allows
196 for incremental searching in a string.
197 Unlike the find iterator, split iterator iterates
198 through gaps between matches.
199
200 Find iterator is a readable forward traversal iterator.
201
202 Dereferencing the iterator yields an iterator_range delimiting
203 the current match.
204 */
205 template<typename IteratorT>
206 class split_iterator :
207 public iterator_facade<
208 split_iterator<IteratorT>,
209 const iterator_range<IteratorT>,
210 forward_traversal_tag >,
211 private detail::find_iterator_base<IteratorT>
212 {
213 private:
214 // facade support
215 friend class ::boost::iterator_core_access;
216
217 private:
218 // typedefs
219
220 typedef detail::find_iterator_base<IteratorT> base_type;
221 typedef BOOST_STRING_TYPENAME
222 base_type::input_iterator_type input_iterator_type;
223 typedef BOOST_STRING_TYPENAME
224 base_type::match_type match_type;
225
226 public:
227 //! Default constructor
228 /*!
229 Construct null iterator. All null iterators are equal.
230
231 \post eof()==true
232 */
233 split_iterator() :
234 m_Next(),
235 m_End(),
236 m_bEof(true)
237 {}
238
239 //! Copy constructor
240 /*!
241 Construct a copy of the split_iterator
242 */
243 split_iterator( const split_iterator& Other ) :
244 base_type(Other),
245 m_Match(Other.m_Match),
246 m_Next(Other.m_Next),
247 m_End(Other.m_End),
248 m_bEof(Other.m_bEof)
249 {}
250
251 //! Constructor
252 /*!
253 Construct new split_iterator for a given finder
254 and a range.
255 */
256 template<typename FinderT>
257 split_iterator(
258 IteratorT Begin,
259 IteratorT End,
260 FinderT Finder ) :
261 detail::find_iterator_base<IteratorT>(Finder,0),
262 m_Match(Begin,Begin),
263 m_Next(Begin),
264 m_End(End),
265 m_bEof(false)
266 {
267 // force the correct behavior for empty sequences and yield at least one token
268 if(Begin!=End)
269 {
270 increment();
271 }
272 }
273 //! Constructor
274 /*!
275 Construct new split_iterator for a given finder
276 and a collection.
277 */
278 template<typename FinderT, typename RangeT>
279 split_iterator(
280 RangeT& Col,
281 FinderT Finder ) :
282 detail::find_iterator_base<IteratorT>(Finder,0),
283 m_bEof(false)
284 {
285 iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
286 m_Match=make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
287 m_Next=::boost::begin(lit_col);
288 m_End=::boost::end(lit_col);
289
290 // force the correct behavior for empty sequences and yield at least one token
291 if(m_Next!=m_End)
292 {
293 increment();
294 }
295 }
296
297
298 private:
299 // iterator operations
300
301 // dereference
302 const match_type& dereference() const
303 {
304 return m_Match;
305 }
306
307 // increment
308 void increment()
309 {
310 match_type FindMatch=this->do_find( m_Next, m_End );
311
312 if(FindMatch.begin()==m_End && FindMatch.end()==m_End)
313 {
314 if(m_Match.end()==m_End)
315 {
316 // Mark iterator as eof
317 m_bEof=true;
318 }
319 }
320
321 m_Match=match_type( m_Next, FindMatch.begin() );
322 m_Next=FindMatch.end();
323 }
324
325 // comparison
326 bool equal( const split_iterator& Other ) const
327 {
328 bool bEof=eof();
329 bool bOtherEof=Other.eof();
330
331 return bEof || bOtherEof ? bEof==bOtherEof :
332 (
333 m_Match==Other.m_Match &&
334 m_Next==Other.m_Next &&
335 m_End==Other.m_End
336 );
337 }
338
339 public:
340 // operations
341
342 //! Eof check
343 /*!
344 Check the eof condition. Eof condition means that
345 there is nothing more to be searched i.e. find_iterator
346 is after the last match.
347 */
348 bool eof() const
349 {
350 return this->is_null() || m_bEof;
351 }
352
353 private:
354 // Attributes
355 match_type m_Match;
356 input_iterator_type m_Next;
357 input_iterator_type m_End;
358 bool m_bEof;
359 };
360
361 //! split iterator construction helper
362 /*!
363 * Construct a split iterator to iterate through the specified collection
364 */
365 template<typename RangeT, typename FinderT>
366 inline split_iterator<
367 BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
368 make_split_iterator(
369 RangeT& Collection,
370 FinderT Finder)
371 {
372 return split_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
373 Collection, Finder);
374 }
375
376
377 } // namespace algorithm
378
379 // pull names to the boost namespace
380 using algorithm::find_iterator;
381 using algorithm::make_find_iterator;
382 using algorithm::split_iterator;
383 using algorithm::make_split_iterator;
384
385} // namespace boost
386
387
388#endif // BOOST_STRING_FIND_ITERATOR_HPP
389

source code of include/boost/algorithm/string/find_iterator.hpp