File indexing completed on 2025-02-22 09:55:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_STRING_FIND_ITERATOR_HPP
0012 #define BOOST_STRING_FIND_ITERATOR_HPP
0013
0014 #include <boost/algorithm/string/config.hpp>
0015 #include <boost/iterator/iterator_facade.hpp>
0016 #include <boost/iterator/iterator_categories.hpp>
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/iterator.hpp>
0022 #include <boost/range/as_literal.hpp>
0023
0024 #include <boost/algorithm/string/detail/find_iterator.hpp>
0025
0026
0027
0028
0029
0030
0031
0032
0033 namespace boost {
0034 namespace algorithm {
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 template<typename IteratorT>
0050 class find_iterator :
0051 public iterator_facade<
0052 find_iterator<IteratorT>,
0053 const iterator_range<IteratorT>,
0054 forward_traversal_tag >,
0055 private detail::find_iterator_base<IteratorT>
0056 {
0057 private:
0058
0059 friend class ::boost::iterator_core_access;
0060
0061 private:
0062
0063
0064 typedef detail::find_iterator_base<IteratorT> base_type;
0065 typedef BOOST_STRING_TYPENAME
0066 base_type::input_iterator_type input_iterator_type;
0067 typedef BOOST_STRING_TYPENAME
0068 base_type::match_type match_type;
0069
0070 public:
0071
0072
0073
0074
0075
0076
0077 BOOST_DEFAULTED_FUNCTION(find_iterator(), {})
0078
0079
0080
0081
0082
0083 find_iterator( const find_iterator& Other ) :
0084 base_type(Other),
0085 m_Match(Other.m_Match),
0086 m_End(Other.m_End) {}
0087
0088
0089
0090
0091
0092 BOOST_DEFAULTED_FUNCTION(find_iterator& operator=( const find_iterator& Other ), {
0093 if (this == &Other) return *this;
0094 this->base_type::operator=(Other);
0095 m_Match = Other.m_Match;
0096 m_End = Other.m_End;
0097 return *this;
0098 })
0099
0100
0101
0102
0103
0104
0105 template<typename FinderT>
0106 find_iterator(
0107 IteratorT Begin,
0108 IteratorT End,
0109 FinderT Finder ) :
0110 detail::find_iterator_base<IteratorT>(Finder,0),
0111 m_Match(Begin,Begin),
0112 m_End(End)
0113 {
0114 increment();
0115 }
0116
0117
0118
0119
0120
0121
0122 template<typename FinderT, typename RangeT>
0123 find_iterator(
0124 RangeT& Col,
0125 FinderT Finder ) :
0126 detail::find_iterator_base<IteratorT>(Finder,0)
0127 {
0128 iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
0129 m_Match=::boost::make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
0130 m_End=::boost::end(lit_col);
0131
0132 increment();
0133 }
0134
0135 private:
0136
0137
0138
0139 const match_type& dereference() const
0140 {
0141 return m_Match;
0142 }
0143
0144
0145 void increment()
0146 {
0147 m_Match=this->do_find(m_Match.end(),m_End);
0148 }
0149
0150
0151 bool equal( const find_iterator& Other ) const
0152 {
0153 bool bEof=eof();
0154 bool bOtherEof=Other.eof();
0155
0156 return bEof || bOtherEof ? bEof==bOtherEof :
0157 (
0158 m_Match==Other.m_Match &&
0159 m_End==Other.m_End
0160 );
0161 }
0162
0163 public:
0164
0165
0166
0167
0168
0169
0170
0171
0172 bool eof() const
0173 {
0174 return
0175 this->is_null() ||
0176 (
0177 m_Match.begin() == m_End &&
0178 m_Match.end() == m_End
0179 );
0180 }
0181
0182 private:
0183
0184 match_type m_Match;
0185 input_iterator_type m_End;
0186 };
0187
0188
0189
0190
0191
0192 template<typename RangeT, typename FinderT>
0193 inline find_iterator<
0194 BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
0195 make_find_iterator(
0196 RangeT& Collection,
0197 FinderT Finder)
0198 {
0199 return find_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
0200 Collection, Finder);
0201 }
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217 template<typename IteratorT>
0218 class split_iterator :
0219 public iterator_facade<
0220 split_iterator<IteratorT>,
0221 const iterator_range<IteratorT>,
0222 forward_traversal_tag >,
0223 private detail::find_iterator_base<IteratorT>
0224 {
0225 private:
0226
0227 friend class ::boost::iterator_core_access;
0228
0229 private:
0230
0231
0232 typedef detail::find_iterator_base<IteratorT> base_type;
0233 typedef BOOST_STRING_TYPENAME
0234 base_type::input_iterator_type input_iterator_type;
0235 typedef BOOST_STRING_TYPENAME
0236 base_type::match_type match_type;
0237
0238 public:
0239
0240
0241
0242
0243
0244
0245 split_iterator() :
0246 m_Next(),
0247 m_End(),
0248 m_bEof(true)
0249 {}
0250
0251
0252
0253
0254
0255 split_iterator( const split_iterator& Other ) :
0256 base_type(Other),
0257 m_Match(Other.m_Match),
0258 m_Next(Other.m_Next),
0259 m_End(Other.m_End),
0260 m_bEof(Other.m_bEof)
0261 {}
0262
0263
0264
0265
0266
0267 BOOST_DEFAULTED_FUNCTION(split_iterator& operator=( const split_iterator& Other ), {
0268 if (this == &Other) return *this;
0269 this->base_type::operator=(Other);
0270 m_Match = Other.m_Match;
0271 m_Next = Other.m_Next;
0272 m_End = Other.m_End;
0273 m_bEof = Other.m_bEof;
0274 return *this;
0275 })
0276
0277
0278
0279
0280
0281
0282 template<typename FinderT>
0283 split_iterator(
0284 IteratorT Begin,
0285 IteratorT End,
0286 FinderT Finder ) :
0287 detail::find_iterator_base<IteratorT>(Finder,0),
0288 m_Match(Begin,Begin),
0289 m_Next(Begin),
0290 m_End(End),
0291 m_bEof(false)
0292 {
0293
0294 if(Begin!=End)
0295 {
0296 increment();
0297 }
0298 }
0299
0300
0301
0302
0303
0304 template<typename FinderT, typename RangeT>
0305 split_iterator(
0306 RangeT& Col,
0307 FinderT Finder ) :
0308 detail::find_iterator_base<IteratorT>(Finder,0),
0309 m_bEof(false)
0310 {
0311 iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
0312 m_Match=make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
0313 m_Next=::boost::begin(lit_col);
0314 m_End=::boost::end(lit_col);
0315
0316
0317 if(m_Next!=m_End)
0318 {
0319 increment();
0320 }
0321 }
0322
0323
0324 private:
0325
0326
0327
0328 const match_type& dereference() const
0329 {
0330 return m_Match;
0331 }
0332
0333
0334 void increment()
0335 {
0336 match_type FindMatch=this->do_find( m_Next, m_End );
0337
0338 if(FindMatch.begin()==m_End && FindMatch.end()==m_End)
0339 {
0340 if(m_Match.end()==m_End)
0341 {
0342
0343 m_bEof=true;
0344 }
0345 }
0346
0347 m_Match=match_type( m_Next, FindMatch.begin() );
0348 m_Next=FindMatch.end();
0349 }
0350
0351
0352 bool equal( const split_iterator& Other ) const
0353 {
0354 bool bEof=eof();
0355 bool bOtherEof=Other.eof();
0356
0357 return bEof || bOtherEof ? bEof==bOtherEof :
0358 (
0359 m_Match==Other.m_Match &&
0360 m_Next==Other.m_Next &&
0361 m_End==Other.m_End
0362 );
0363 }
0364
0365 public:
0366
0367
0368
0369
0370
0371
0372
0373
0374 bool eof() const
0375 {
0376 return this->is_null() || m_bEof;
0377 }
0378
0379 private:
0380
0381 match_type m_Match;
0382 input_iterator_type m_Next;
0383 input_iterator_type m_End;
0384 bool m_bEof;
0385 };
0386
0387
0388
0389
0390
0391 template<typename RangeT, typename FinderT>
0392 inline split_iterator<
0393 BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
0394 make_split_iterator(
0395 RangeT& Collection,
0396 FinderT Finder)
0397 {
0398 return split_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
0399 Collection, Finder);
0400 }
0401
0402
0403 }
0404
0405
0406 using algorithm::find_iterator;
0407 using algorithm::make_find_iterator;
0408 using algorithm::split_iterator;
0409 using algorithm::make_split_iterator;
0410
0411 }
0412
0413
0414 #endif