Chris@16
|
1 // Boost string_algo library finder.hpp header file ---------------------------//
|
Chris@16
|
2
|
Chris@16
|
3 // Copyright Pavol Droba 2002-2006.
|
Chris@16
|
4 //
|
Chris@16
|
5 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
6 // (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8
|
Chris@16
|
9 // See http://www.boost.org/ for updates, documentation, and revision history.
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_STRING_FINDER_DETAIL_HPP
|
Chris@16
|
12 #define BOOST_STRING_FINDER_DETAIL_HPP
|
Chris@16
|
13
|
Chris@16
|
14 #include <boost/algorithm/string/config.hpp>
|
Chris@16
|
15 #include <boost/algorithm/string/constants.hpp>
|
Chris@16
|
16 #include <boost/detail/iterator.hpp>
|
Chris@16
|
17
|
Chris@16
|
18 #include <boost/range/iterator_range_core.hpp>
|
Chris@16
|
19 #include <boost/range/begin.hpp>
|
Chris@16
|
20 #include <boost/range/end.hpp>
|
Chris@16
|
21 #include <boost/range/empty.hpp>
|
Chris@16
|
22 #include <boost/range/as_literal.hpp>
|
Chris@16
|
23
|
Chris@16
|
24 namespace boost {
|
Chris@16
|
25 namespace algorithm {
|
Chris@16
|
26 namespace detail {
|
Chris@16
|
27
|
Chris@16
|
28
|
Chris@16
|
29 // find first functor -----------------------------------------------//
|
Chris@16
|
30
|
Chris@16
|
31 // find a subsequence in the sequence ( functor )
|
Chris@16
|
32 /*
|
Chris@16
|
33 Returns a pair <begin,end> marking the subsequence in the sequence.
|
Chris@16
|
34 If the find fails, functor returns <End,End>
|
Chris@16
|
35 */
|
Chris@16
|
36 template<typename SearchIteratorT,typename PredicateT>
|
Chris@16
|
37 struct first_finderF
|
Chris@16
|
38 {
|
Chris@16
|
39 typedef SearchIteratorT search_iterator_type;
|
Chris@16
|
40
|
Chris@16
|
41 // Construction
|
Chris@16
|
42 template< typename SearchT >
|
Chris@16
|
43 first_finderF( const SearchT& Search, PredicateT Comp ) :
|
Chris@16
|
44 m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {}
|
Chris@16
|
45 first_finderF(
|
Chris@16
|
46 search_iterator_type SearchBegin,
|
Chris@16
|
47 search_iterator_type SearchEnd,
|
Chris@16
|
48 PredicateT Comp ) :
|
Chris@16
|
49 m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {}
|
Chris@16
|
50
|
Chris@16
|
51 // Operation
|
Chris@16
|
52 template< typename ForwardIteratorT >
|
Chris@16
|
53 iterator_range<ForwardIteratorT>
|
Chris@16
|
54 operator()(
|
Chris@16
|
55 ForwardIteratorT Begin,
|
Chris@16
|
56 ForwardIteratorT End ) const
|
Chris@16
|
57 {
|
Chris@16
|
58 typedef iterator_range<ForwardIteratorT> result_type;
|
Chris@16
|
59 typedef ForwardIteratorT input_iterator_type;
|
Chris@16
|
60
|
Chris@16
|
61 // Outer loop
|
Chris@16
|
62 for(input_iterator_type OuterIt=Begin;
|
Chris@16
|
63 OuterIt!=End;
|
Chris@16
|
64 ++OuterIt)
|
Chris@16
|
65 {
|
Chris@16
|
66 // Sanity check
|
Chris@16
|
67 if( boost::empty(m_Search) )
|
Chris@16
|
68 return result_type( End, End );
|
Chris@16
|
69
|
Chris@16
|
70 input_iterator_type InnerIt=OuterIt;
|
Chris@16
|
71 search_iterator_type SubstrIt=m_Search.begin();
|
Chris@16
|
72 for(;
|
Chris@16
|
73 InnerIt!=End && SubstrIt!=m_Search.end();
|
Chris@16
|
74 ++InnerIt,++SubstrIt)
|
Chris@16
|
75 {
|
Chris@16
|
76 if( !( m_Comp(*InnerIt,*SubstrIt) ) )
|
Chris@16
|
77 break;
|
Chris@16
|
78 }
|
Chris@16
|
79
|
Chris@16
|
80 // Substring matching succeeded
|
Chris@16
|
81 if ( SubstrIt==m_Search.end() )
|
Chris@16
|
82 return result_type( OuterIt, InnerIt );
|
Chris@16
|
83 }
|
Chris@16
|
84
|
Chris@16
|
85 return result_type( End, End );
|
Chris@16
|
86 }
|
Chris@16
|
87
|
Chris@16
|
88 private:
|
Chris@16
|
89 iterator_range<search_iterator_type> m_Search;
|
Chris@16
|
90 PredicateT m_Comp;
|
Chris@16
|
91 };
|
Chris@16
|
92
|
Chris@16
|
93 // find last functor -----------------------------------------------//
|
Chris@16
|
94
|
Chris@16
|
95 // find the last match a subsequence in the sequence ( functor )
|
Chris@16
|
96 /*
|
Chris@16
|
97 Returns a pair <begin,end> marking the subsequence in the sequence.
|
Chris@16
|
98 If the find fails, returns <End,End>
|
Chris@16
|
99 */
|
Chris@16
|
100 template<typename SearchIteratorT, typename PredicateT>
|
Chris@16
|
101 struct last_finderF
|
Chris@16
|
102 {
|
Chris@16
|
103 typedef SearchIteratorT search_iterator_type;
|
Chris@16
|
104 typedef first_finderF<
|
Chris@16
|
105 search_iterator_type,
|
Chris@16
|
106 PredicateT> first_finder_type;
|
Chris@16
|
107
|
Chris@16
|
108 // Construction
|
Chris@16
|
109 template< typename SearchT >
|
Chris@16
|
110 last_finderF( const SearchT& Search, PredicateT Comp ) :
|
Chris@16
|
111 m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {}
|
Chris@16
|
112 last_finderF(
|
Chris@16
|
113 search_iterator_type SearchBegin,
|
Chris@16
|
114 search_iterator_type SearchEnd,
|
Chris@16
|
115 PredicateT Comp ) :
|
Chris@16
|
116 m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {}
|
Chris@16
|
117
|
Chris@16
|
118 // Operation
|
Chris@16
|
119 template< typename ForwardIteratorT >
|
Chris@16
|
120 iterator_range<ForwardIteratorT>
|
Chris@16
|
121 operator()(
|
Chris@16
|
122 ForwardIteratorT Begin,
|
Chris@16
|
123 ForwardIteratorT End ) const
|
Chris@16
|
124 {
|
Chris@16
|
125 typedef iterator_range<ForwardIteratorT> result_type;
|
Chris@16
|
126
|
Chris@16
|
127 if( boost::empty(m_Search) )
|
Chris@16
|
128 return result_type( End, End );
|
Chris@16
|
129
|
Chris@16
|
130 typedef BOOST_STRING_TYPENAME boost::detail::
|
Chris@16
|
131 iterator_traits<ForwardIteratorT>::iterator_category category;
|
Chris@16
|
132
|
Chris@16
|
133 return findit( Begin, End, category() );
|
Chris@16
|
134 }
|
Chris@16
|
135
|
Chris@16
|
136 private:
|
Chris@16
|
137 // forward iterator
|
Chris@16
|
138 template< typename ForwardIteratorT >
|
Chris@16
|
139 iterator_range<ForwardIteratorT>
|
Chris@16
|
140 findit(
|
Chris@16
|
141 ForwardIteratorT Begin,
|
Chris@16
|
142 ForwardIteratorT End,
|
Chris@16
|
143 std::forward_iterator_tag ) const
|
Chris@16
|
144 {
|
Chris@16
|
145 typedef iterator_range<ForwardIteratorT> result_type;
|
Chris@16
|
146
|
Chris@16
|
147 first_finder_type first_finder(
|
Chris@16
|
148 m_Search.begin(), m_Search.end(), m_Comp );
|
Chris@16
|
149
|
Chris@16
|
150 result_type M=first_finder( Begin, End );
|
Chris@16
|
151 result_type Last=M;
|
Chris@16
|
152
|
Chris@16
|
153 while( M )
|
Chris@16
|
154 {
|
Chris@16
|
155 Last=M;
|
Chris@16
|
156 M=first_finder( ::boost::end(M), End );
|
Chris@16
|
157 }
|
Chris@16
|
158
|
Chris@16
|
159 return Last;
|
Chris@16
|
160 }
|
Chris@16
|
161
|
Chris@16
|
162 // bidirectional iterator
|
Chris@16
|
163 template< typename ForwardIteratorT >
|
Chris@16
|
164 iterator_range<ForwardIteratorT>
|
Chris@16
|
165 findit(
|
Chris@16
|
166 ForwardIteratorT Begin,
|
Chris@16
|
167 ForwardIteratorT End,
|
Chris@16
|
168 std::bidirectional_iterator_tag ) const
|
Chris@16
|
169 {
|
Chris@16
|
170 typedef iterator_range<ForwardIteratorT> result_type;
|
Chris@16
|
171 typedef ForwardIteratorT input_iterator_type;
|
Chris@16
|
172
|
Chris@16
|
173 // Outer loop
|
Chris@16
|
174 for(input_iterator_type OuterIt=End;
|
Chris@16
|
175 OuterIt!=Begin; )
|
Chris@16
|
176 {
|
Chris@16
|
177 input_iterator_type OuterIt2=--OuterIt;
|
Chris@16
|
178
|
Chris@16
|
179 input_iterator_type InnerIt=OuterIt2;
|
Chris@16
|
180 search_iterator_type SubstrIt=m_Search.begin();
|
Chris@16
|
181 for(;
|
Chris@16
|
182 InnerIt!=End && SubstrIt!=m_Search.end();
|
Chris@16
|
183 ++InnerIt,++SubstrIt)
|
Chris@16
|
184 {
|
Chris@16
|
185 if( !( m_Comp(*InnerIt,*SubstrIt) ) )
|
Chris@16
|
186 break;
|
Chris@16
|
187 }
|
Chris@16
|
188
|
Chris@16
|
189 // Substring matching succeeded
|
Chris@16
|
190 if( SubstrIt==m_Search.end() )
|
Chris@16
|
191 return result_type( OuterIt2, InnerIt );
|
Chris@16
|
192 }
|
Chris@16
|
193
|
Chris@16
|
194 return result_type( End, End );
|
Chris@16
|
195 }
|
Chris@16
|
196
|
Chris@16
|
197 private:
|
Chris@16
|
198 iterator_range<search_iterator_type> m_Search;
|
Chris@16
|
199 PredicateT m_Comp;
|
Chris@16
|
200 };
|
Chris@16
|
201
|
Chris@16
|
202 // find n-th functor -----------------------------------------------//
|
Chris@16
|
203
|
Chris@16
|
204 // find the n-th match of a subsequence in the sequence ( functor )
|
Chris@16
|
205 /*
|
Chris@16
|
206 Returns a pair <begin,end> marking the subsequence in the sequence.
|
Chris@16
|
207 If the find fails, returns <End,End>
|
Chris@16
|
208 */
|
Chris@16
|
209 template<typename SearchIteratorT, typename PredicateT>
|
Chris@16
|
210 struct nth_finderF
|
Chris@16
|
211 {
|
Chris@16
|
212 typedef SearchIteratorT search_iterator_type;
|
Chris@16
|
213 typedef first_finderF<
|
Chris@16
|
214 search_iterator_type,
|
Chris@16
|
215 PredicateT> first_finder_type;
|
Chris@16
|
216 typedef last_finderF<
|
Chris@16
|
217 search_iterator_type,
|
Chris@16
|
218 PredicateT> last_finder_type;
|
Chris@16
|
219
|
Chris@16
|
220 // Construction
|
Chris@16
|
221 template< typename SearchT >
|
Chris@16
|
222 nth_finderF(
|
Chris@16
|
223 const SearchT& Search,
|
Chris@16
|
224 int Nth,
|
Chris@16
|
225 PredicateT Comp) :
|
Chris@16
|
226 m_Search(::boost::begin(Search), ::boost::end(Search)),
|
Chris@16
|
227 m_Nth(Nth),
|
Chris@16
|
228 m_Comp(Comp) {}
|
Chris@16
|
229 nth_finderF(
|
Chris@16
|
230 search_iterator_type SearchBegin,
|
Chris@16
|
231 search_iterator_type SearchEnd,
|
Chris@16
|
232 int Nth,
|
Chris@16
|
233 PredicateT Comp) :
|
Chris@16
|
234 m_Search(SearchBegin, SearchEnd),
|
Chris@16
|
235 m_Nth(Nth),
|
Chris@16
|
236 m_Comp(Comp) {}
|
Chris@16
|
237
|
Chris@16
|
238 // Operation
|
Chris@16
|
239 template< typename ForwardIteratorT >
|
Chris@16
|
240 iterator_range<ForwardIteratorT>
|
Chris@16
|
241 operator()(
|
Chris@16
|
242 ForwardIteratorT Begin,
|
Chris@16
|
243 ForwardIteratorT End ) const
|
Chris@16
|
244 {
|
Chris@16
|
245 if(m_Nth>=0)
|
Chris@16
|
246 {
|
Chris@16
|
247 return find_forward(Begin, End, m_Nth);
|
Chris@16
|
248 }
|
Chris@16
|
249 else
|
Chris@16
|
250 {
|
Chris@16
|
251 return find_backward(Begin, End, -m_Nth);
|
Chris@16
|
252 }
|
Chris@16
|
253
|
Chris@16
|
254 }
|
Chris@16
|
255
|
Chris@16
|
256 private:
|
Chris@16
|
257 // Implementation helpers
|
Chris@16
|
258 template< typename ForwardIteratorT >
|
Chris@16
|
259 iterator_range<ForwardIteratorT>
|
Chris@16
|
260 find_forward(
|
Chris@16
|
261 ForwardIteratorT Begin,
|
Chris@16
|
262 ForwardIteratorT End,
|
Chris@16
|
263 unsigned int N) const
|
Chris@16
|
264 {
|
Chris@16
|
265 typedef iterator_range<ForwardIteratorT> result_type;
|
Chris@16
|
266
|
Chris@16
|
267 // Sanity check
|
Chris@16
|
268 if( boost::empty(m_Search) )
|
Chris@16
|
269 return result_type( End, End );
|
Chris@16
|
270
|
Chris@16
|
271 // Instantiate find functor
|
Chris@16
|
272 first_finder_type first_finder(
|
Chris@16
|
273 m_Search.begin(), m_Search.end(), m_Comp );
|
Chris@16
|
274
|
Chris@16
|
275 result_type M( Begin, Begin );
|
Chris@16
|
276
|
Chris@16
|
277 for( unsigned int n=0; n<=N; ++n )
|
Chris@16
|
278 {
|
Chris@16
|
279 // find next match
|
Chris@16
|
280 M=first_finder( ::boost::end(M), End );
|
Chris@16
|
281
|
Chris@16
|
282 if ( !M )
|
Chris@16
|
283 {
|
Chris@16
|
284 // Subsequence not found, return
|
Chris@16
|
285 return M;
|
Chris@16
|
286 }
|
Chris@16
|
287 }
|
Chris@16
|
288
|
Chris@16
|
289 return M;
|
Chris@16
|
290 }
|
Chris@16
|
291
|
Chris@16
|
292 template< typename ForwardIteratorT >
|
Chris@16
|
293 iterator_range<ForwardIteratorT>
|
Chris@16
|
294 find_backward(
|
Chris@16
|
295 ForwardIteratorT Begin,
|
Chris@16
|
296 ForwardIteratorT End,
|
Chris@16
|
297 unsigned int N) const
|
Chris@16
|
298 {
|
Chris@16
|
299 typedef iterator_range<ForwardIteratorT> result_type;
|
Chris@16
|
300
|
Chris@16
|
301 // Sanity check
|
Chris@16
|
302 if( boost::empty(m_Search) )
|
Chris@16
|
303 return result_type( End, End );
|
Chris@16
|
304
|
Chris@16
|
305 // Instantiate find functor
|
Chris@16
|
306 last_finder_type last_finder(
|
Chris@16
|
307 m_Search.begin(), m_Search.end(), m_Comp );
|
Chris@16
|
308
|
Chris@16
|
309 result_type M( End, End );
|
Chris@16
|
310
|
Chris@16
|
311 for( unsigned int n=1; n<=N; ++n )
|
Chris@16
|
312 {
|
Chris@16
|
313 // find next match
|
Chris@16
|
314 M=last_finder( Begin, ::boost::begin(M) );
|
Chris@16
|
315
|
Chris@16
|
316 if ( !M )
|
Chris@16
|
317 {
|
Chris@16
|
318 // Subsequence not found, return
|
Chris@16
|
319 return M;
|
Chris@16
|
320 }
|
Chris@16
|
321 }
|
Chris@16
|
322
|
Chris@16
|
323 return M;
|
Chris@16
|
324 }
|
Chris@16
|
325
|
Chris@16
|
326
|
Chris@16
|
327 private:
|
Chris@16
|
328 iterator_range<search_iterator_type> m_Search;
|
Chris@16
|
329 int m_Nth;
|
Chris@16
|
330 PredicateT m_Comp;
|
Chris@16
|
331 };
|
Chris@16
|
332
|
Chris@16
|
333 // find head/tail implementation helpers ---------------------------//
|
Chris@16
|
334
|
Chris@16
|
335 template<typename ForwardIteratorT>
|
Chris@16
|
336 iterator_range<ForwardIteratorT>
|
Chris@16
|
337 find_head_impl(
|
Chris@16
|
338 ForwardIteratorT Begin,
|
Chris@16
|
339 ForwardIteratorT End,
|
Chris@16
|
340 unsigned int N,
|
Chris@16
|
341 std::forward_iterator_tag )
|
Chris@16
|
342 {
|
Chris@16
|
343 typedef ForwardIteratorT input_iterator_type;
|
Chris@16
|
344 typedef iterator_range<ForwardIteratorT> result_type;
|
Chris@16
|
345
|
Chris@16
|
346 input_iterator_type It=Begin;
|
Chris@16
|
347 for(
|
Chris@16
|
348 unsigned int Index=0;
|
Chris@16
|
349 Index<N && It!=End; ++Index,++It ) {};
|
Chris@16
|
350
|
Chris@16
|
351 return result_type( Begin, It );
|
Chris@16
|
352 }
|
Chris@16
|
353
|
Chris@16
|
354 template< typename ForwardIteratorT >
|
Chris@16
|
355 iterator_range<ForwardIteratorT>
|
Chris@16
|
356 find_head_impl(
|
Chris@16
|
357 ForwardIteratorT Begin,
|
Chris@16
|
358 ForwardIteratorT End,
|
Chris@16
|
359 unsigned int N,
|
Chris@16
|
360 std::random_access_iterator_tag )
|
Chris@16
|
361 {
|
Chris@16
|
362 typedef iterator_range<ForwardIteratorT> result_type;
|
Chris@16
|
363
|
Chris@16
|
364 if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
|
Chris@16
|
365 return result_type( Begin, End );
|
Chris@16
|
366
|
Chris@16
|
367 return result_type(Begin,Begin+N);
|
Chris@16
|
368 }
|
Chris@16
|
369
|
Chris@16
|
370 // Find head implementation
|
Chris@16
|
371 template<typename ForwardIteratorT>
|
Chris@16
|
372 iterator_range<ForwardIteratorT>
|
Chris@16
|
373 find_head_impl(
|
Chris@16
|
374 ForwardIteratorT Begin,
|
Chris@16
|
375 ForwardIteratorT End,
|
Chris@16
|
376 unsigned int N )
|
Chris@16
|
377 {
|
Chris@16
|
378 typedef BOOST_STRING_TYPENAME boost::detail::
|
Chris@16
|
379 iterator_traits<ForwardIteratorT>::iterator_category category;
|
Chris@16
|
380
|
Chris@16
|
381 return ::boost::algorithm::detail::find_head_impl( Begin, End, N, category() );
|
Chris@16
|
382 }
|
Chris@16
|
383
|
Chris@16
|
384 template< typename ForwardIteratorT >
|
Chris@16
|
385 iterator_range<ForwardIteratorT>
|
Chris@16
|
386 find_tail_impl(
|
Chris@16
|
387 ForwardIteratorT Begin,
|
Chris@16
|
388 ForwardIteratorT End,
|
Chris@16
|
389 unsigned int N,
|
Chris@16
|
390 std::forward_iterator_tag )
|
Chris@16
|
391 {
|
Chris@16
|
392 typedef ForwardIteratorT input_iterator_type;
|
Chris@16
|
393 typedef iterator_range<ForwardIteratorT> result_type;
|
Chris@16
|
394
|
Chris@16
|
395 unsigned int Index=0;
|
Chris@16
|
396 input_iterator_type It=Begin;
|
Chris@16
|
397 input_iterator_type It2=Begin;
|
Chris@16
|
398
|
Chris@16
|
399 // Advance It2 by N increments
|
Chris@16
|
400 for( Index=0; Index<N && It2!=End; ++Index,++It2 ) {};
|
Chris@16
|
401
|
Chris@16
|
402 // Advance It, It2 to the end
|
Chris@16
|
403 for(; It2!=End; ++It,++It2 ) {};
|
Chris@16
|
404
|
Chris@16
|
405 return result_type( It, It2 );
|
Chris@16
|
406 }
|
Chris@16
|
407
|
Chris@16
|
408 template< typename ForwardIteratorT >
|
Chris@16
|
409 iterator_range<ForwardIteratorT>
|
Chris@16
|
410 find_tail_impl(
|
Chris@16
|
411 ForwardIteratorT Begin,
|
Chris@16
|
412 ForwardIteratorT End,
|
Chris@16
|
413 unsigned int N,
|
Chris@16
|
414 std::bidirectional_iterator_tag )
|
Chris@16
|
415 {
|
Chris@16
|
416 typedef ForwardIteratorT input_iterator_type;
|
Chris@16
|
417 typedef iterator_range<ForwardIteratorT> result_type;
|
Chris@16
|
418
|
Chris@16
|
419 input_iterator_type It=End;
|
Chris@16
|
420 for(
|
Chris@16
|
421 unsigned int Index=0;
|
Chris@16
|
422 Index<N && It!=Begin; ++Index,--It ) {};
|
Chris@16
|
423
|
Chris@16
|
424 return result_type( It, End );
|
Chris@16
|
425 }
|
Chris@16
|
426
|
Chris@16
|
427 template< typename ForwardIteratorT >
|
Chris@16
|
428 iterator_range<ForwardIteratorT>
|
Chris@16
|
429 find_tail_impl(
|
Chris@16
|
430 ForwardIteratorT Begin,
|
Chris@16
|
431 ForwardIteratorT End,
|
Chris@16
|
432 unsigned int N,
|
Chris@16
|
433 std::random_access_iterator_tag )
|
Chris@16
|
434 {
|
Chris@16
|
435 typedef iterator_range<ForwardIteratorT> result_type;
|
Chris@16
|
436
|
Chris@16
|
437 if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
|
Chris@16
|
438 return result_type( Begin, End );
|
Chris@16
|
439
|
Chris@16
|
440 return result_type( End-N, End );
|
Chris@16
|
441 }
|
Chris@16
|
442
|
Chris@16
|
443 // Operation
|
Chris@16
|
444 template< typename ForwardIteratorT >
|
Chris@16
|
445 iterator_range<ForwardIteratorT>
|
Chris@16
|
446 find_tail_impl(
|
Chris@16
|
447 ForwardIteratorT Begin,
|
Chris@16
|
448 ForwardIteratorT End,
|
Chris@16
|
449 unsigned int N )
|
Chris@16
|
450 {
|
Chris@16
|
451 typedef BOOST_STRING_TYPENAME boost::detail::
|
Chris@16
|
452 iterator_traits<ForwardIteratorT>::iterator_category category;
|
Chris@16
|
453
|
Chris@16
|
454 return ::boost::algorithm::detail::find_tail_impl( Begin, End, N, category() );
|
Chris@16
|
455 }
|
Chris@16
|
456
|
Chris@16
|
457
|
Chris@16
|
458
|
Chris@16
|
459 // find head functor -----------------------------------------------//
|
Chris@16
|
460
|
Chris@16
|
461
|
Chris@16
|
462 // find a head in the sequence ( functor )
|
Chris@16
|
463 /*
|
Chris@16
|
464 This functor find a head of the specified range. For
|
Chris@16
|
465 a specified N, the head is a subsequence of N starting
|
Chris@16
|
466 elements of the range.
|
Chris@16
|
467 */
|
Chris@16
|
468 struct head_finderF
|
Chris@16
|
469 {
|
Chris@16
|
470 // Construction
|
Chris@16
|
471 head_finderF( int N ) : m_N(N) {}
|
Chris@16
|
472
|
Chris@16
|
473 // Operation
|
Chris@16
|
474 template< typename ForwardIteratorT >
|
Chris@16
|
475 iterator_range<ForwardIteratorT>
|
Chris@16
|
476 operator()(
|
Chris@16
|
477 ForwardIteratorT Begin,
|
Chris@16
|
478 ForwardIteratorT End ) const
|
Chris@16
|
479 {
|
Chris@16
|
480 if(m_N>=0)
|
Chris@16
|
481 {
|
Chris@16
|
482 return ::boost::algorithm::detail::find_head_impl( Begin, End, m_N );
|
Chris@16
|
483 }
|
Chris@16
|
484 else
|
Chris@16
|
485 {
|
Chris@16
|
486 iterator_range<ForwardIteratorT> Res=
|
Chris@16
|
487 ::boost::algorithm::detail::find_tail_impl( Begin, End, -m_N );
|
Chris@16
|
488
|
Chris@16
|
489 return ::boost::make_iterator_range(Begin, Res.begin());
|
Chris@16
|
490 }
|
Chris@16
|
491 }
|
Chris@16
|
492
|
Chris@16
|
493 private:
|
Chris@16
|
494 int m_N;
|
Chris@16
|
495 };
|
Chris@16
|
496
|
Chris@16
|
497 // find tail functor -----------------------------------------------//
|
Chris@16
|
498
|
Chris@16
|
499
|
Chris@16
|
500 // find a tail in the sequence ( functor )
|
Chris@16
|
501 /*
|
Chris@16
|
502 This functor find a tail of the specified range. For
|
Chris@16
|
503 a specified N, the head is a subsequence of N starting
|
Chris@16
|
504 elements of the range.
|
Chris@16
|
505 */
|
Chris@16
|
506 struct tail_finderF
|
Chris@16
|
507 {
|
Chris@16
|
508 // Construction
|
Chris@16
|
509 tail_finderF( int N ) : m_N(N) {}
|
Chris@16
|
510
|
Chris@16
|
511 // Operation
|
Chris@16
|
512 template< typename ForwardIteratorT >
|
Chris@16
|
513 iterator_range<ForwardIteratorT>
|
Chris@16
|
514 operator()(
|
Chris@16
|
515 ForwardIteratorT Begin,
|
Chris@16
|
516 ForwardIteratorT End ) const
|
Chris@16
|
517 {
|
Chris@16
|
518 if(m_N>=0)
|
Chris@16
|
519 {
|
Chris@16
|
520 return ::boost::algorithm::detail::find_tail_impl( Begin, End, m_N );
|
Chris@16
|
521 }
|
Chris@16
|
522 else
|
Chris@16
|
523 {
|
Chris@16
|
524 iterator_range<ForwardIteratorT> Res=
|
Chris@16
|
525 ::boost::algorithm::detail::find_head_impl( Begin, End, -m_N );
|
Chris@16
|
526
|
Chris@16
|
527 return ::boost::make_iterator_range(Res.end(), End);
|
Chris@16
|
528 }
|
Chris@16
|
529 }
|
Chris@16
|
530
|
Chris@16
|
531 private:
|
Chris@16
|
532 int m_N;
|
Chris@16
|
533 };
|
Chris@16
|
534
|
Chris@16
|
535 // find token functor -----------------------------------------------//
|
Chris@16
|
536
|
Chris@16
|
537 // find a token in a sequence ( functor )
|
Chris@16
|
538 /*
|
Chris@16
|
539 This find functor finds a token specified be a predicate
|
Chris@16
|
540 in a sequence. It is equivalent of std::find algorithm,
|
Chris@16
|
541 with an exception that it return range instead of a single
|
Chris@16
|
542 iterator.
|
Chris@16
|
543
|
Chris@16
|
544 If bCompress is set to true, adjacent matching tokens are
|
Chris@16
|
545 concatenated into one match.
|
Chris@16
|
546 */
|
Chris@16
|
547 template< typename PredicateT >
|
Chris@16
|
548 struct token_finderF
|
Chris@16
|
549 {
|
Chris@16
|
550 // Construction
|
Chris@16
|
551 token_finderF(
|
Chris@16
|
552 PredicateT Pred,
|
Chris@16
|
553 token_compress_mode_type eCompress=token_compress_off ) :
|
Chris@16
|
554 m_Pred(Pred), m_eCompress(eCompress) {}
|
Chris@16
|
555
|
Chris@16
|
556 // Operation
|
Chris@16
|
557 template< typename ForwardIteratorT >
|
Chris@16
|
558 iterator_range<ForwardIteratorT>
|
Chris@16
|
559 operator()(
|
Chris@16
|
560 ForwardIteratorT Begin,
|
Chris@16
|
561 ForwardIteratorT End ) const
|
Chris@16
|
562 {
|
Chris@16
|
563 typedef iterator_range<ForwardIteratorT> result_type;
|
Chris@16
|
564
|
Chris@16
|
565 ForwardIteratorT It=std::find_if( Begin, End, m_Pred );
|
Chris@16
|
566
|
Chris@16
|
567 if( It==End )
|
Chris@16
|
568 {
|
Chris@16
|
569 return result_type( End, End );
|
Chris@16
|
570 }
|
Chris@16
|
571 else
|
Chris@16
|
572 {
|
Chris@16
|
573 ForwardIteratorT It2=It;
|
Chris@16
|
574
|
Chris@16
|
575 if( m_eCompress==token_compress_on )
|
Chris@16
|
576 {
|
Chris@16
|
577 // Find first non-matching character
|
Chris@16
|
578 while( It2!=End && m_Pred(*It2) ) ++It2;
|
Chris@16
|
579 }
|
Chris@16
|
580 else
|
Chris@16
|
581 {
|
Chris@16
|
582 // Advance by one position
|
Chris@16
|
583 ++It2;
|
Chris@16
|
584 }
|
Chris@16
|
585
|
Chris@16
|
586 return result_type( It, It2 );
|
Chris@16
|
587 }
|
Chris@16
|
588 }
|
Chris@16
|
589
|
Chris@16
|
590 private:
|
Chris@16
|
591 PredicateT m_Pred;
|
Chris@16
|
592 token_compress_mode_type m_eCompress;
|
Chris@16
|
593 };
|
Chris@16
|
594
|
Chris@16
|
595 // find range functor -----------------------------------------------//
|
Chris@16
|
596
|
Chris@16
|
597 // find a range in the sequence ( functor )
|
Chris@16
|
598 /*
|
Chris@16
|
599 This functor actually does not perform any find operation.
|
Chris@16
|
600 It always returns given iterator range as a result.
|
Chris@16
|
601 */
|
Chris@16
|
602 template<typename ForwardIterator1T>
|
Chris@16
|
603 struct range_finderF
|
Chris@16
|
604 {
|
Chris@16
|
605 typedef ForwardIterator1T input_iterator_type;
|
Chris@16
|
606 typedef iterator_range<input_iterator_type> result_type;
|
Chris@16
|
607
|
Chris@16
|
608 // Construction
|
Chris@16
|
609 range_finderF(
|
Chris@16
|
610 input_iterator_type Begin,
|
Chris@16
|
611 input_iterator_type End ) : m_Range(Begin, End) {}
|
Chris@16
|
612
|
Chris@16
|
613 range_finderF(const iterator_range<input_iterator_type>& Range) :
|
Chris@16
|
614 m_Range(Range) {}
|
Chris@16
|
615
|
Chris@16
|
616 // Operation
|
Chris@16
|
617 template< typename ForwardIterator2T >
|
Chris@16
|
618 iterator_range<ForwardIterator2T>
|
Chris@16
|
619 operator()(
|
Chris@16
|
620 ForwardIterator2T,
|
Chris@16
|
621 ForwardIterator2T ) const
|
Chris@16
|
622 {
|
Chris@16
|
623 #if BOOST_WORKAROUND( __MWERKS__, <= 0x3003 )
|
Chris@16
|
624 return iterator_range<const ForwardIterator2T>(this->m_Range);
|
Chris@16
|
625 #else
|
Chris@16
|
626 return m_Range;
|
Chris@16
|
627 #endif
|
Chris@16
|
628 }
|
Chris@16
|
629
|
Chris@16
|
630 private:
|
Chris@16
|
631 iterator_range<input_iterator_type> m_Range;
|
Chris@16
|
632 };
|
Chris@16
|
633
|
Chris@16
|
634
|
Chris@16
|
635 } // namespace detail
|
Chris@16
|
636 } // namespace algorithm
|
Chris@16
|
637 } // namespace boost
|
Chris@16
|
638
|
Chris@16
|
639 #endif // BOOST_STRING_FINDER_DETAIL_HPP
|