Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2003
4 : * John Maddock
5 : *
6 : * Use, modification and distribution are subject to the
7 : * Boost Software License, Version 1.0. (See accompanying file
8 : * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 : *
10 : */
11 :
12 : /*
13 : * LOCATION: see http://www.boost.org for most recent version.
14 : * FILE regex_iterator.hpp
15 : * VERSION see <boost/version.hpp>
16 : * DESCRIPTION: Provides regex_iterator implementation.
17 : */
18 :
19 : #ifndef BOOST_REGEX_V4_REGEX_ITERATOR_HPP
20 : #define BOOST_REGEX_V4_REGEX_ITERATOR_HPP
21 :
22 : #include <boost/shared_ptr.hpp>
23 :
24 : namespace boost{
25 :
26 : #ifdef BOOST_MSVC
27 : #pragma warning(push)
28 : #pragma warning(disable: 4103)
29 : #endif
30 : #ifdef BOOST_HAS_ABI_HEADERS
31 : # include BOOST_ABI_PREFIX
32 : #endif
33 : #ifdef BOOST_MSVC
34 : #pragma warning(pop)
35 : #endif
36 :
37 : template <class BidirectionalIterator,
38 : class charT,
39 : class traits>
40 : class regex_iterator_implementation
41 : {
42 : typedef basic_regex<charT, traits> regex_type;
43 :
44 : match_results<BidirectionalIterator> what; // current match
45 : BidirectionalIterator base; // start of sequence
46 : BidirectionalIterator end; // end of sequence
47 : const regex_type re; // the expression
48 : match_flag_type flags; // flags for matching
49 :
50 : public:
51 0 : regex_iterator_implementation(const regex_type* p, BidirectionalIterator last, match_flag_type f)
52 0 : : base(), end(last), re(*p), flags(f){}
53 0 : bool init(BidirectionalIterator first)
54 : {
55 0 : base = first;
56 0 : return regex_search(first, end, what, re, flags);
57 : }
58 0 : bool compare(const regex_iterator_implementation& that)
59 : {
60 0 : if(this == &that) return true;
61 0 : return (&re.get_data() == &that.re.get_data()) && (end == that.end) && (flags == that.flags) && (what[0].first == that.what[0].first) && (what[0].second == that.what[0].second);
62 : }
63 0 : const match_results<BidirectionalIterator>& get()
64 0 : { return what; }
65 0 : bool next()
66 : {
67 : //if(what.prefix().first != what[0].second)
68 : // flags |= match_prev_avail;
69 0 : BidirectionalIterator next_start = what[0].second;
70 0 : match_flag_type f(flags);
71 0 : if(!what.length() || (f & regex_constants::match_posix))
72 0 : f |= regex_constants::match_not_initial_null;
73 : //if(base != next_start)
74 : // f |= regex_constants::match_not_bob;
75 0 : bool result = regex_search(next_start, end, what, re, f, base);
76 0 : if(result)
77 0 : what.set_base(base);
78 0 : return result;
79 : }
80 : private:
81 : regex_iterator_implementation& operator=(const regex_iterator_implementation&);
82 : };
83 :
84 : template <class BidirectionalIterator,
85 : class charT = BOOST_DEDUCED_TYPENAME BOOST_REGEX_DETAIL_NS::regex_iterator_traits<BidirectionalIterator>::value_type,
86 : class traits = regex_traits<charT> >
87 0 : class regex_iterator
88 : {
89 : private:
90 : typedef regex_iterator_implementation<BidirectionalIterator, charT, traits> impl;
91 : typedef shared_ptr<impl> pimpl;
92 : public:
93 : typedef basic_regex<charT, traits> regex_type;
94 : typedef match_results<BidirectionalIterator> value_type;
95 : typedef typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<BidirectionalIterator>::difference_type
96 : difference_type;
97 : typedef const value_type* pointer;
98 : typedef const value_type& reference;
99 : typedef std::forward_iterator_tag iterator_category;
100 :
101 0 : regex_iterator(){}
102 0 : regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
103 : const regex_type& re,
104 : match_flag_type m = match_default)
105 0 : : pdata(new impl(&re, b, m))
106 : {
107 0 : if(!pdata->init(a))
108 : {
109 0 : pdata.reset();
110 : }
111 0 : }
112 : regex_iterator(const regex_iterator& that)
113 : : pdata(that.pdata) {}
114 : regex_iterator& operator=(const regex_iterator& that)
115 : {
116 : pdata = that.pdata;
117 : return *this;
118 : }
119 0 : bool operator==(const regex_iterator& that)const
120 : {
121 0 : if((pdata.get() == 0) || (that.pdata.get() == 0))
122 0 : return pdata.get() == that.pdata.get();
123 0 : return pdata->compare(*(that.pdata.get()));
124 : }
125 0 : bool operator!=(const regex_iterator& that)const
126 0 : { return !(*this == that); }
127 0 : const value_type& operator*()const
128 0 : { return pdata->get(); }
129 0 : const value_type* operator->()const
130 0 : { return &(pdata->get()); }
131 0 : regex_iterator& operator++()
132 : {
133 0 : cow();
134 0 : if(0 == pdata->next())
135 : {
136 0 : pdata.reset();
137 : }
138 0 : return *this;
139 : }
140 : regex_iterator operator++(int)
141 : {
142 : regex_iterator result(*this);
143 : ++(*this);
144 : return result;
145 : }
146 : private:
147 :
148 : pimpl pdata;
149 :
150 0 : void cow()
151 : {
152 : // copy-on-write
153 0 : if(pdata.get() && !pdata.unique())
154 : {
155 0 : pdata.reset(new impl(*(pdata.get())));
156 : }
157 0 : }
158 : };
159 :
160 : typedef regex_iterator<const char*> cregex_iterator;
161 : typedef regex_iterator<std::string::const_iterator> sregex_iterator;
162 : #ifndef BOOST_NO_WREGEX
163 : typedef regex_iterator<const wchar_t*> wcregex_iterator;
164 : typedef regex_iterator<std::wstring::const_iterator> wsregex_iterator;
165 : #endif
166 :
167 : // make_regex_iterator:
168 : template <class charT, class traits>
169 : inline regex_iterator<const charT*, charT, traits> make_regex_iterator(const charT* p, const basic_regex<charT, traits>& e, regex_constants::match_flag_type m = regex_constants::match_default)
170 : {
171 : return regex_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, m);
172 : }
173 : template <class charT, class traits, class ST, class SA>
174 : inline regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, regex_constants::match_flag_type m = regex_constants::match_default)
175 : {
176 : return regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, m);
177 : }
178 :
179 : #ifdef BOOST_MSVC
180 : #pragma warning(push)
181 : #pragma warning(disable: 4103)
182 : #endif
183 : #ifdef BOOST_HAS_ABI_HEADERS
184 : # include BOOST_ABI_SUFFIX
185 : #endif
186 : #ifdef BOOST_MSVC
187 : #pragma warning(pop)
188 : #endif
189 :
190 : } // namespace boost
191 :
192 : #endif // BOOST_REGEX_V4_REGEX_ITERATOR_HPP
193 :
|