source: NonGTP/Boost/boost/algorithm/string/find_iterator.hpp @ 857

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