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 BOOST_DEFAULTED_FUNCTION(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 //! Copy assignment
89 /*!
90 Assigns a copy of the find_iterator
91 */
92 BOOST_DEFAULTED_FUNCTION(find_iterator& operator=( const find_iterator& Other ), {
93 if (this == &Other) return *this;
94 this->base_type::operator=(Other);
95 m_Match = Other.m_Match;
96 m_End = Other.m_End;
97 return *this;
98 })
99
100 //! Constructor
101 /*!
102 Construct new find_iterator for a given finder
103 and a range.
104 */
105 template<typename FinderT>
106 find_iterator(
107 IteratorT Begin,
108 IteratorT End,
109 FinderT Finder ) :
110 detail::find_iterator_base<IteratorT>(Finder,0),
111 m_Match(Begin,Begin),
112 m_End(End)
113 {
114 increment();
115 }
116
117 //! Constructor
118 /*!
119 Construct new find_iterator for a given finder
120 and a range.
121 */
122 template<typename FinderT, typename RangeT>
123 find_iterator(
124 RangeT& Col,
125 FinderT Finder ) :
126 detail::find_iterator_base<IteratorT>(Finder,0)
127 {
128 iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
129 m_Match=::boost::make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
130 m_End=::boost::end(lit_col);
131
132 increment();
133 }
134
135 private:
136 // iterator operations
137
138 // dereference
139 const match_type& dereference() const
140 {
141 return m_Match;
142 }
143
144 // increment
145 void increment()
146 {
147 m_Match=this->do_find(m_Match.end(),m_End);
148 }
149
150 // comparison
151 bool equal( const find_iterator& Other ) const
152 {
153 bool bEof=eof();
154 bool bOtherEof=Other.eof();
155
156 return bEof || bOtherEof ? bEof==bOtherEof :
157 (
158 m_Match==Other.m_Match &&
159 m_End==Other.m_End
160 );
161 }
162
163 public:
164 // operations
165
166 //! Eof check
167 /*!
168 Check the eof condition. Eof condition means that
169 there is nothing more to be searched i.e. find_iterator
170 is after the last match.
171 */
172 bool eof() const
173 {
174 return
175 this->is_null() ||
176 (
177 m_Match.begin() == m_End &&
178 m_Match.end() == m_End
179 );
180 }
181
182 private:
183 // Attributes
184 match_type m_Match;
185 input_iterator_type m_End;
186 };
187
188 //! find iterator construction helper
189 /*!
190 * Construct a find iterator to iterate through the specified string
191 */
192 template<typename RangeT, typename FinderT>
193 inline find_iterator<
194 BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
195 make_find_iterator(
196 RangeT& Collection,
197 FinderT Finder)
198 {
199 return find_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
200 Collection, Finder);
201 }
202
203// split iterator -----------------------------------------------//
204
205 //! split_iterator
206 /*!
207 Split iterator encapsulates a Finder and allows
208 for incremental searching in a string.
209 Unlike the find iterator, split iterator iterates
210 through gaps between matches.
211
212 Find iterator is a readable forward traversal iterator.
213
214 Dereferencing the iterator yields an iterator_range delimiting
215 the current match.
216 */
217 template<typename IteratorT>
218 class split_iterator :
219 public iterator_facade<
220 split_iterator<IteratorT>,
221 const iterator_range<IteratorT>,
222 forward_traversal_tag >,
223 private detail::find_iterator_base<IteratorT>
224 {
225 private:
226 // facade support
227 friend class ::boost::iterator_core_access;
228
229 private:
230 // typedefs
231
232 typedef detail::find_iterator_base<IteratorT> base_type;
233 typedef BOOST_STRING_TYPENAME
234 base_type::input_iterator_type input_iterator_type;
235 typedef BOOST_STRING_TYPENAME
236 base_type::match_type match_type;
237
238 public:
239 //! Default constructor
240 /*!
241 Construct null iterator. All null iterators are equal.
242
243 \post eof()==true
244 */
245 split_iterator() :
246 m_Next(),
247 m_End(),
248 m_bEof(true)
249 {}
250
251 //! Copy constructor
252 /*!
253 Construct a copy of the split_iterator
254 */
255 split_iterator( const split_iterator& Other ) :
256 base_type(Other),
257 m_Match(Other.m_Match),
258 m_Next(Other.m_Next),
259 m_End(Other.m_End),
260 m_bEof(Other.m_bEof)
261 {}
262
263 //! Assignment operator
264 /*!
265 Assigns a copy of the split_iterator
266 */
267 BOOST_DEFAULTED_FUNCTION(split_iterator& operator=( const split_iterator& Other ), {
268 if (this == &Other) return *this;
269 this->base_type::operator=(Other);
270 m_Match = Other.m_Match;
271 m_Next = Other.m_Next;
272 m_End = Other.m_End;
273 m_bEof = Other.m_bEof;
274 return *this;
275 })
276
277 //! Constructor
278 /*!
279 Construct new split_iterator for a given finder
280 and a range.
281 */
282 template<typename FinderT>
283 split_iterator(
284 IteratorT Begin,
285 IteratorT End,
286 FinderT Finder ) :
287 detail::find_iterator_base<IteratorT>(Finder,0),
288 m_Match(Begin,Begin),
289 m_Next(Begin),
290 m_End(End),
291 m_bEof(false)
292 {
293 // force the correct behavior for empty sequences and yield at least one token
294 if(Begin!=End)
295 {
296 increment();
297 }
298 }
299 //! Constructor
300 /*!
301 Construct new split_iterator for a given finder
302 and a collection.
303 */
304 template<typename FinderT, typename RangeT>
305 split_iterator(
306 RangeT& Col,
307 FinderT Finder ) :
308 detail::find_iterator_base<IteratorT>(Finder,0),
309 m_bEof(false)
310 {
311 iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
312 m_Match=make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
313 m_Next=::boost::begin(lit_col);
314 m_End=::boost::end(lit_col);
315
316 // force the correct behavior for empty sequences and yield at least one token
317 if(m_Next!=m_End)
318 {
319 increment();
320 }
321 }
322
323
324 private:
325 // iterator operations
326
327 // dereference
328 const match_type& dereference() const
329 {
330 return m_Match;
331 }
332
333 // increment
334 void increment()
335 {
336 match_type FindMatch=this->do_find( m_Next, m_End );
337
338 if(FindMatch.begin()==m_End && FindMatch.end()==m_End)
339 {
340 if(m_Match.end()==m_End)
341 {
342 // Mark iterator as eof
343 m_bEof=true;
344 }
345 }
346
347 m_Match=match_type( m_Next, FindMatch.begin() );
348 m_Next=FindMatch.end();
349 }
350
351 // comparison
352 bool equal( const split_iterator& Other ) const
353 {
354 bool bEof=eof();
355 bool bOtherEof=Other.eof();
356
357 return bEof || bOtherEof ? bEof==bOtherEof :
358 (
359 m_Match==Other.m_Match &&
360 m_Next==Other.m_Next &&
361 m_End==Other.m_End
362 );
363 }
364
365 public:
366 // operations
367
368 //! Eof check
369 /*!
370 Check the eof condition. Eof condition means that
371 there is nothing more to be searched i.e. find_iterator
372 is after the last match.
373 */
374 bool eof() const
375 {
376 return this->is_null() || m_bEof;
377 }
378
379 private:
380 // Attributes
381 match_type m_Match;
382 input_iterator_type m_Next;
383 input_iterator_type m_End;
384 bool m_bEof;
385 };
386
387 //! split iterator construction helper
388 /*!
389 * Construct a split iterator to iterate through the specified collection
390 */
391 template<typename RangeT, typename FinderT>
392 inline split_iterator<
393 BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
394 make_split_iterator(
395 RangeT& Collection,
396 FinderT Finder)
397 {
398 return split_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
399 Collection, Finder);
400 }
401
402
403 } // namespace algorithm
404
405 // pull names to the boost namespace
406 using algorithm::find_iterator;
407 using algorithm::make_find_iterator;
408 using algorithm::split_iterator;
409 using algorithm::make_split_iterator;
410
411} // namespace boost
412
413
414#endif // BOOST_STRING_FIND_ITERATOR_HPP
415

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