File indexing completed on 2025-01-18 09:28:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_STRING_FINDER_DETAIL_HPP
0012 #define BOOST_STRING_FINDER_DETAIL_HPP
0013
0014 #include <boost/algorithm/string/config.hpp>
0015 #include <boost/algorithm/string/constants.hpp>
0016 #include <iterator>
0017
0018 #include <boost/range/iterator_range_core.hpp>
0019 #include <boost/range/begin.hpp>
0020 #include <boost/range/end.hpp>
0021 #include <boost/range/empty.hpp>
0022 #include <boost/range/as_literal.hpp>
0023
0024 namespace boost {
0025 namespace algorithm {
0026 namespace detail {
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 template<typename SearchIteratorT,typename PredicateT>
0037 struct first_finderF
0038 {
0039 typedef SearchIteratorT search_iterator_type;
0040
0041
0042 template< typename SearchT >
0043 first_finderF( const SearchT& Search, PredicateT Comp ) :
0044 m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {}
0045 first_finderF(
0046 search_iterator_type SearchBegin,
0047 search_iterator_type SearchEnd,
0048 PredicateT Comp ) :
0049 m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {}
0050
0051
0052 template< typename ForwardIteratorT >
0053 iterator_range<ForwardIteratorT>
0054 operator()(
0055 ForwardIteratorT Begin,
0056 ForwardIteratorT End ) const
0057 {
0058 typedef iterator_range<ForwardIteratorT> result_type;
0059 typedef ForwardIteratorT input_iterator_type;
0060
0061
0062 for(input_iterator_type OuterIt=Begin;
0063 OuterIt!=End;
0064 ++OuterIt)
0065 {
0066
0067 if( boost::empty(m_Search) )
0068 return result_type( End, End );
0069
0070 input_iterator_type InnerIt=OuterIt;
0071 search_iterator_type SubstrIt=m_Search.begin();
0072 for(;
0073 InnerIt!=End && SubstrIt!=m_Search.end();
0074 ++InnerIt,++SubstrIt)
0075 {
0076 if( !( m_Comp(*InnerIt,*SubstrIt) ) )
0077 break;
0078 }
0079
0080
0081 if ( SubstrIt==m_Search.end() )
0082 return result_type( OuterIt, InnerIt );
0083 }
0084
0085 return result_type( End, End );
0086 }
0087
0088 private:
0089 iterator_range<search_iterator_type> m_Search;
0090 PredicateT m_Comp;
0091 };
0092
0093
0094
0095
0096
0097
0098
0099
0100 template<typename SearchIteratorT, typename PredicateT>
0101 struct last_finderF
0102 {
0103 typedef SearchIteratorT search_iterator_type;
0104 typedef first_finderF<
0105 search_iterator_type,
0106 PredicateT> first_finder_type;
0107
0108
0109 template< typename SearchT >
0110 last_finderF( const SearchT& Search, PredicateT Comp ) :
0111 m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {}
0112 last_finderF(
0113 search_iterator_type SearchBegin,
0114 search_iterator_type SearchEnd,
0115 PredicateT Comp ) :
0116 m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {}
0117
0118
0119 template< typename ForwardIteratorT >
0120 iterator_range<ForwardIteratorT>
0121 operator()(
0122 ForwardIteratorT Begin,
0123 ForwardIteratorT End ) const
0124 {
0125 typedef iterator_range<ForwardIteratorT> result_type;
0126
0127 if( boost::empty(m_Search) )
0128 return result_type( End, End );
0129
0130 typedef BOOST_STRING_TYPENAME
0131 std::iterator_traits<ForwardIteratorT>::iterator_category category;
0132
0133 return findit( Begin, End, category() );
0134 }
0135
0136 private:
0137
0138 template< typename ForwardIteratorT >
0139 iterator_range<ForwardIteratorT>
0140 findit(
0141 ForwardIteratorT Begin,
0142 ForwardIteratorT End,
0143 std::forward_iterator_tag ) const
0144 {
0145 typedef iterator_range<ForwardIteratorT> result_type;
0146
0147 first_finder_type first_finder(
0148 m_Search.begin(), m_Search.end(), m_Comp );
0149
0150 result_type M=first_finder( Begin, End );
0151 result_type Last=M;
0152
0153 while( M )
0154 {
0155 Last=M;
0156 M=first_finder( ::boost::end(M), End );
0157 }
0158
0159 return Last;
0160 }
0161
0162
0163 template< typename ForwardIteratorT >
0164 iterator_range<ForwardIteratorT>
0165 findit(
0166 ForwardIteratorT Begin,
0167 ForwardIteratorT End,
0168 std::bidirectional_iterator_tag ) const
0169 {
0170 typedef iterator_range<ForwardIteratorT> result_type;
0171 typedef ForwardIteratorT input_iterator_type;
0172
0173
0174 for(input_iterator_type OuterIt=End;
0175 OuterIt!=Begin; )
0176 {
0177 input_iterator_type OuterIt2=--OuterIt;
0178
0179 input_iterator_type InnerIt=OuterIt2;
0180 search_iterator_type SubstrIt=m_Search.begin();
0181 for(;
0182 InnerIt!=End && SubstrIt!=m_Search.end();
0183 ++InnerIt,++SubstrIt)
0184 {
0185 if( !( m_Comp(*InnerIt,*SubstrIt) ) )
0186 break;
0187 }
0188
0189
0190 if( SubstrIt==m_Search.end() )
0191 return result_type( OuterIt2, InnerIt );
0192 }
0193
0194 return result_type( End, End );
0195 }
0196
0197 private:
0198 iterator_range<search_iterator_type> m_Search;
0199 PredicateT m_Comp;
0200 };
0201
0202
0203
0204
0205
0206
0207
0208
0209 template<typename SearchIteratorT, typename PredicateT>
0210 struct nth_finderF
0211 {
0212 typedef SearchIteratorT search_iterator_type;
0213 typedef first_finderF<
0214 search_iterator_type,
0215 PredicateT> first_finder_type;
0216 typedef last_finderF<
0217 search_iterator_type,
0218 PredicateT> last_finder_type;
0219
0220
0221 template< typename SearchT >
0222 nth_finderF(
0223 const SearchT& Search,
0224 int Nth,
0225 PredicateT Comp) :
0226 m_Search(::boost::begin(Search), ::boost::end(Search)),
0227 m_Nth(Nth),
0228 m_Comp(Comp) {}
0229 nth_finderF(
0230 search_iterator_type SearchBegin,
0231 search_iterator_type SearchEnd,
0232 int Nth,
0233 PredicateT Comp) :
0234 m_Search(SearchBegin, SearchEnd),
0235 m_Nth(Nth),
0236 m_Comp(Comp) {}
0237
0238
0239 template< typename ForwardIteratorT >
0240 iterator_range<ForwardIteratorT>
0241 operator()(
0242 ForwardIteratorT Begin,
0243 ForwardIteratorT End ) const
0244 {
0245 if(m_Nth>=0)
0246 {
0247 return find_forward(Begin, End, m_Nth);
0248 }
0249 else
0250 {
0251 return find_backward(Begin, End, -m_Nth);
0252 }
0253
0254 }
0255
0256 private:
0257
0258 template< typename ForwardIteratorT >
0259 iterator_range<ForwardIteratorT>
0260 find_forward(
0261 ForwardIteratorT Begin,
0262 ForwardIteratorT End,
0263 unsigned int N) const
0264 {
0265 typedef iterator_range<ForwardIteratorT> result_type;
0266
0267
0268 if( boost::empty(m_Search) )
0269 return result_type( End, End );
0270
0271
0272 first_finder_type first_finder(
0273 m_Search.begin(), m_Search.end(), m_Comp );
0274
0275 result_type M( Begin, Begin );
0276
0277 for( unsigned int n=0; n<=N; ++n )
0278 {
0279
0280 M=first_finder( ::boost::end(M), End );
0281
0282 if ( !M )
0283 {
0284
0285 return M;
0286 }
0287 }
0288
0289 return M;
0290 }
0291
0292 template< typename ForwardIteratorT >
0293 iterator_range<ForwardIteratorT>
0294 find_backward(
0295 ForwardIteratorT Begin,
0296 ForwardIteratorT End,
0297 unsigned int N) const
0298 {
0299 typedef iterator_range<ForwardIteratorT> result_type;
0300
0301
0302 if( boost::empty(m_Search) )
0303 return result_type( End, End );
0304
0305
0306 last_finder_type last_finder(
0307 m_Search.begin(), m_Search.end(), m_Comp );
0308
0309 result_type M( End, End );
0310
0311 for( unsigned int n=1; n<=N; ++n )
0312 {
0313
0314 M=last_finder( Begin, ::boost::begin(M) );
0315
0316 if ( !M )
0317 {
0318
0319 return M;
0320 }
0321 }
0322
0323 return M;
0324 }
0325
0326
0327 private:
0328 iterator_range<search_iterator_type> m_Search;
0329 int m_Nth;
0330 PredicateT m_Comp;
0331 };
0332
0333
0334
0335 template<typename ForwardIteratorT>
0336 iterator_range<ForwardIteratorT>
0337 find_head_impl(
0338 ForwardIteratorT Begin,
0339 ForwardIteratorT End,
0340 unsigned int N,
0341 std::forward_iterator_tag )
0342 {
0343 typedef ForwardIteratorT input_iterator_type;
0344 typedef iterator_range<ForwardIteratorT> result_type;
0345
0346 input_iterator_type It=Begin;
0347 for( unsigned int Index=0; Index<N && It!=End; ++Index,++It )
0348 ;
0349
0350 return result_type( Begin, It );
0351 }
0352
0353 template< typename ForwardIteratorT >
0354 iterator_range<ForwardIteratorT>
0355 find_head_impl(
0356 ForwardIteratorT Begin,
0357 ForwardIteratorT End,
0358 unsigned int N,
0359 std::random_access_iterator_tag )
0360 {
0361 typedef iterator_range<ForwardIteratorT> result_type;
0362
0363 if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
0364 return result_type( Begin, End );
0365
0366 return result_type(Begin,Begin+N);
0367 }
0368
0369
0370 template<typename ForwardIteratorT>
0371 iterator_range<ForwardIteratorT>
0372 find_head_impl(
0373 ForwardIteratorT Begin,
0374 ForwardIteratorT End,
0375 unsigned int N )
0376 {
0377 typedef BOOST_STRING_TYPENAME
0378 std::iterator_traits<ForwardIteratorT>::iterator_category category;
0379
0380 return ::boost::algorithm::detail::find_head_impl( Begin, End, N, category() );
0381 }
0382
0383 template< typename ForwardIteratorT >
0384 iterator_range<ForwardIteratorT>
0385 find_tail_impl(
0386 ForwardIteratorT Begin,
0387 ForwardIteratorT End,
0388 unsigned int N,
0389 std::forward_iterator_tag )
0390 {
0391 typedef ForwardIteratorT input_iterator_type;
0392 typedef iterator_range<ForwardIteratorT> result_type;
0393
0394 unsigned int Index=0;
0395 input_iterator_type It=Begin;
0396 input_iterator_type It2=Begin;
0397
0398
0399 for( Index=0; Index<N && It2!=End; ++Index,++It2 )
0400 ;
0401
0402
0403 for(; It2!=End; ++It,++It2 )
0404 ;
0405
0406 return result_type( It, It2 );
0407 }
0408
0409 template< typename ForwardIteratorT >
0410 iterator_range<ForwardIteratorT>
0411 find_tail_impl(
0412 ForwardIteratorT Begin,
0413 ForwardIteratorT End,
0414 unsigned int N,
0415 std::bidirectional_iterator_tag )
0416 {
0417 typedef ForwardIteratorT input_iterator_type;
0418 typedef iterator_range<ForwardIteratorT> result_type;
0419
0420 input_iterator_type It=End;
0421 for( unsigned int Index=0; Index<N && It!=Begin; ++Index,--It )
0422 ;
0423
0424 return result_type( It, End );
0425 }
0426
0427 template< typename ForwardIteratorT >
0428 iterator_range<ForwardIteratorT>
0429 find_tail_impl(
0430 ForwardIteratorT Begin,
0431 ForwardIteratorT End,
0432 unsigned int N,
0433 std::random_access_iterator_tag )
0434 {
0435 typedef iterator_range<ForwardIteratorT> result_type;
0436
0437 if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
0438 return result_type( Begin, End );
0439
0440 return result_type( End-N, End );
0441 }
0442
0443
0444 template< typename ForwardIteratorT >
0445 iterator_range<ForwardIteratorT>
0446 find_tail_impl(
0447 ForwardIteratorT Begin,
0448 ForwardIteratorT End,
0449 unsigned int N )
0450 {
0451 typedef BOOST_STRING_TYPENAME
0452 std::iterator_traits<ForwardIteratorT>::iterator_category category;
0453
0454 return ::boost::algorithm::detail::find_tail_impl( Begin, End, N, category() );
0455 }
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468 struct head_finderF
0469 {
0470
0471 head_finderF( int N ) : m_N(N) {}
0472
0473
0474 template< typename ForwardIteratorT >
0475 iterator_range<ForwardIteratorT>
0476 operator()(
0477 ForwardIteratorT Begin,
0478 ForwardIteratorT End ) const
0479 {
0480 if(m_N>=0)
0481 {
0482 return ::boost::algorithm::detail::find_head_impl( Begin, End, m_N );
0483 }
0484 else
0485 {
0486 iterator_range<ForwardIteratorT> Res=
0487 ::boost::algorithm::detail::find_tail_impl( Begin, End, -m_N );
0488
0489 return ::boost::make_iterator_range(Begin, Res.begin());
0490 }
0491 }
0492
0493 private:
0494 int m_N;
0495 };
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506 struct tail_finderF
0507 {
0508
0509 tail_finderF( int N ) : m_N(N) {}
0510
0511
0512 template< typename ForwardIteratorT >
0513 iterator_range<ForwardIteratorT>
0514 operator()(
0515 ForwardIteratorT Begin,
0516 ForwardIteratorT End ) const
0517 {
0518 if(m_N>=0)
0519 {
0520 return ::boost::algorithm::detail::find_tail_impl( Begin, End, m_N );
0521 }
0522 else
0523 {
0524 iterator_range<ForwardIteratorT> Res=
0525 ::boost::algorithm::detail::find_head_impl( Begin, End, -m_N );
0526
0527 return ::boost::make_iterator_range(Res.end(), End);
0528 }
0529 }
0530
0531 private:
0532 int m_N;
0533 };
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547 template< typename PredicateT >
0548 struct token_finderF
0549 {
0550
0551 token_finderF(
0552 PredicateT Pred,
0553 token_compress_mode_type eCompress=token_compress_off ) :
0554 m_Pred(Pred), m_eCompress(eCompress) {}
0555
0556
0557 template< typename ForwardIteratorT >
0558 iterator_range<ForwardIteratorT>
0559 operator()(
0560 ForwardIteratorT Begin,
0561 ForwardIteratorT End ) const
0562 {
0563 typedef iterator_range<ForwardIteratorT> result_type;
0564
0565 ForwardIteratorT It=std::find_if( Begin, End, m_Pred );
0566
0567 if( It==End )
0568 {
0569 return result_type( End, End );
0570 }
0571 else
0572 {
0573 ForwardIteratorT It2=It;
0574
0575 if( m_eCompress==token_compress_on )
0576 {
0577
0578 while( It2!=End && m_Pred(*It2) ) ++It2;
0579 }
0580 else
0581 {
0582
0583 ++It2;
0584 }
0585
0586 return result_type( It, It2 );
0587 }
0588 }
0589
0590 private:
0591 PredicateT m_Pred;
0592 token_compress_mode_type m_eCompress;
0593 };
0594
0595
0596
0597
0598
0599
0600
0601
0602 template<typename ForwardIterator1T>
0603 struct range_finderF
0604 {
0605 typedef ForwardIterator1T input_iterator_type;
0606 typedef iterator_range<input_iterator_type> result_type;
0607
0608
0609 range_finderF(
0610 input_iterator_type Begin,
0611 input_iterator_type End ) : m_Range(Begin, End) {}
0612
0613 range_finderF(const iterator_range<input_iterator_type>& Range) :
0614 m_Range(Range) {}
0615
0616
0617 template< typename ForwardIterator2T >
0618 iterator_range<ForwardIterator2T>
0619 operator()(
0620 ForwardIterator2T,
0621 ForwardIterator2T ) const
0622 {
0623 #if BOOST_WORKAROUND( __MWERKS__, <= 0x3003 )
0624 return iterator_range<const ForwardIterator2T>(this->m_Range);
0625 #else
0626 return m_Range;
0627 #endif
0628 }
0629
0630 private:
0631 iterator_range<input_iterator_type> m_Range;
0632 };
0633
0634
0635 }
0636 }
0637 }
0638
0639 #endif