source: NonGTP/Boost/boost/regex/v4/regex_token_iterator.hpp @ 857

Revision 857, 13.0 KB checked in by igarcia, 18 years ago (diff)
Line 
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_token_iterator.hpp
15  *   VERSION      see <boost/version.hpp>
16  *   DESCRIPTION: Provides regex_token_iterator implementation.
17  */
18
19#ifndef BOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP
20#define BOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP
21
22#include <boost/shared_ptr.hpp>
23#include <boost/detail/workaround.hpp>
24#if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\
25      || BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
26      || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
27//
28// Borland C++ Builder 6, and Visual C++ 6,
29// can't cope with the array template constructor
30// so we have a template member that will accept any type as
31// argument, and then assert that is really is an array:
32//
33#include <boost/static_assert.hpp>
34#include <boost/type_traits/is_array.hpp>
35#endif
36
37namespace boost{
38
39#ifdef BOOST_HAS_ABI_HEADERS
40#  include BOOST_ABI_PREFIX
41#endif
42#if BOOST_WORKAROUND(BOOST_MSVC, > 1300)
43#  pragma warning(push)
44#  pragma warning(disable:4700)
45#endif
46
47template <class BidirectionalIterator,
48          class charT,
49          class traits>
50class regex_token_iterator_implementation
51{
52   typedef basic_regex<charT, traits> regex_type;
53   typedef sub_match<BidirectionalIterator>      value_type;
54
55   match_results<BidirectionalIterator> what;   // current match
56   BidirectionalIterator                base;    // start of search area
57   BidirectionalIterator                end;    // end of search area
58   const regex_type                     re;    // the expression
59   match_flag_type                      flags;  // match flags
60   value_type                           result; // the current string result
61   int                                  N;      // the current sub-expression being enumerated
62   std::vector<int>                     subs;   // the sub-expressions to enumerate
63
64public:
65   regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, int sub, match_flag_type f)
66      : end(last), re(*p), flags(f){ subs.push_back(sub); }
67   regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const std::vector<int>& v, match_flag_type f)
68      : end(last), re(*p), flags(f), subs(v){}
69#if !BOOST_WORKAROUND(__HP_aCC, BOOST_TESTED_AT(55500))
70#if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\
71      || BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
72      || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) \
73      || BOOST_WORKAROUND(__HP_aCC, BOOST_TESTED_AT(55500))
74   template <class T>
75   regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const T& submatches, match_flag_type f)
76      : end(last), re(*p), flags(f)
77   {
78      // assert that T really is an array:
79      BOOST_STATIC_ASSERT(::boost::is_array<T>::value);
80      const std::size_t array_size = sizeof(T) / sizeof(submatches[0]);
81      for(std::size_t i = 0; i < array_size; ++i)
82      {
83         subs.push_back(submatches[i]);
84      }
85   }
86#else
87   template <std::size_t CN>
88   regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const int (&submatches)[CN], match_flag_type f)
89      : end(last), re(*p), flags(f)
90   {
91      for(std::size_t i = 0; i < CN; ++i)
92      {
93         subs.push_back(submatches[i]);
94      }
95   }
96#endif
97#endif
98   bool init(BidirectionalIterator first)
99   {
100      N = 0;
101      base = first;
102      if(regex_search(first, end, what, re, flags, base) == true)
103      {
104         N = 0;
105         result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]);
106         return true;
107      }
108      else if((subs[N] == -1) && (first != end))
109      {
110         result.first = first;
111         result.second = end;
112         result.matched = (first != end);
113         return true;
114      }
115      return false;
116   }
117   bool compare(const regex_token_iterator_implementation& that)
118   {
119      if(this == &that) return true;
120      return (&re.get_data() == &that.re.get_data())
121         && (end == that.end)
122         && (flags == that.flags)
123         && (N == that.N)
124         && (what[0].first == that.what[0].first)
125         && (what[0].second == that.what[0].second);
126   }
127   const value_type& get()
128   { return result; }
129   bool next()
130   {
131      if(N == -1)
132         return false;
133      if(N+1 < (int)subs.size())
134      {
135         ++N;
136         result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
137         return true;
138      }
139      //if(what.prefix().first != what[0].second)
140      //   flags |= /*match_prev_avail |*/ regex_constants::match_not_bob;
141      BidirectionalIterator last_end(what[0].second);
142      if(regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags), base))
143      {
144         N =0;
145         result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
146         return true;
147      }
148      else if((last_end != end) && (subs[0] == -1))
149      {
150         N =-1;
151         result.first = last_end;
152         result.second = end;
153         result.matched = (last_end != end);
154         return true;
155      }
156      return false;
157   }
158private:
159   regex_token_iterator_implementation& operator=(const regex_token_iterator_implementation&);
160};
161
162template <class BidirectionalIterator,
163          class charT = BOOST_DEDUCED_TYPENAME re_detail::regex_iterator_traits<BidirectionalIterator>::value_type,
164          class traits = regex_traits<charT> >
165class regex_token_iterator
166#ifndef BOOST_NO_STD_ITERATOR
167   : public std::iterator<
168         std::forward_iterator_tag,
169         sub_match<BidirectionalIterator>,
170         typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type,
171         const sub_match<BidirectionalIterator>*,
172         const sub_match<BidirectionalIterator>& >         
173#endif
174{
175private:
176   typedef regex_token_iterator_implementation<BidirectionalIterator, charT, traits> impl;
177   typedef shared_ptr<impl> pimpl;
178public:
179   typedef          basic_regex<charT, traits>                   regex_type;
180   typedef          sub_match<BidirectionalIterator>                        value_type;
181   typedef typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type
182                                                                            difference_type;
183   typedef          const value_type*                                       pointer;
184   typedef          const value_type&                                       reference;
185   typedef          std::forward_iterator_tag                               iterator_category;
186   
187   regex_token_iterator(){}
188   regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
189                        int submatch = 0, match_flag_type m = match_default)
190                        : pdata(new impl(&re, b, submatch, m))
191   {
192      if(!pdata->init(a))
193         pdata.reset();
194   }
195   regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
196                        const std::vector<int>& submatches, match_flag_type m = match_default)
197                        : pdata(new impl(&re, b, submatches, m))
198   {
199      if(!pdata->init(a))
200         pdata.reset();
201   }
202#if !BOOST_WORKAROUND(__HP_aCC, BOOST_TESTED_AT(55500))
203#if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\
204      || BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
205      || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) \
206      || BOOST_WORKAROUND(__HP_aCC, BOOST_TESTED_AT(55500))
207   template <class T>
208   regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
209                        const T& submatches, match_flag_type m = match_default)
210                        : pdata(new impl(&re, b, submatches, m))
211   {
212      if(!pdata->init(a))
213         pdata.reset();
214   }
215#else
216   template <std::size_t N>
217   regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
218                        const int (&submatches)[N], match_flag_type m = match_default)
219                        : pdata(new impl(&re, b, submatches, m))
220   {
221      if(!pdata->init(a))
222         pdata.reset();
223   }
224#endif
225#endif
226   regex_token_iterator(const regex_token_iterator& that)
227      : pdata(that.pdata) {}
228   regex_token_iterator& operator=(const regex_token_iterator& that)
229   {
230      pdata = that.pdata;
231      return *this;
232   }
233   bool operator==(const regex_token_iterator& that)const
234   {
235      if((pdata.get() == 0) || (that.pdata.get() == 0))
236         return pdata.get() == that.pdata.get();
237      return pdata->compare(*(that.pdata.get()));
238   }
239   bool operator!=(const regex_token_iterator& that)const
240   { return !(*this == that); }
241   const value_type& operator*()const
242   { return pdata->get(); }
243   const value_type* operator->()const
244   { return &(pdata->get()); }
245   regex_token_iterator& operator++()
246   {
247      cow();
248      if(0 == pdata->next())
249      {
250         pdata.reset();
251      }
252      return *this;
253   }
254   regex_token_iterator operator++(int)
255   {
256      regex_token_iterator result(*this);
257      ++(*this);
258      return result;
259   }
260private:
261
262   pimpl pdata;
263
264   void cow()
265   {
266      // copy-on-write
267      if(pdata.get() && !pdata.unique())
268      {
269         pdata.reset(new impl(*(pdata.get())));
270      }
271   }
272};
273
274typedef regex_token_iterator<const char*> cregex_token_iterator;
275typedef regex_token_iterator<std::string::const_iterator> sregex_token_iterator;
276#ifndef BOOST_NO_WREGEX
277typedef regex_token_iterator<const wchar_t*> wcregex_token_iterator;
278typedef regex_token_iterator<std::wstring::const_iterator> wsregex_token_iterator;
279#endif
280
281template <class charT, class traits>
282inline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
283{
284   return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);
285}
286template <class charT, class traits, class ST, class SA>
287inline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
288{
289   return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);
290}
291#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
292template <class charT, class traits, std::size_t N>
293inline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
294{
295   return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);
296}
297template <class charT, class traits, class ST, class SA, std::size_t N>
298inline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
299{
300   return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);
301}
302#endif
303template <class charT, class traits>
304inline regex_token_iterator<const charT*, charT, traits> make_regex_token_iterator(const charT* p, const basic_regex<charT, traits>& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
305{
306   return regex_token_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, submatch, m);
307}
308template <class charT, class traits, class ST, class SA>
309inline regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits> make_regex_token_iterator(const std::basic_string<charT, ST, SA>& p, const basic_regex<charT, traits>& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
310{
311   return regex_token_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, submatch, m);
312}
313
314#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
315#  pragma warning(pop)
316#endif
317#ifdef BOOST_HAS_ABI_HEADERS
318#  include BOOST_ABI_SUFFIX
319#endif
320
321} // namespace boost
322
323#endif // BOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP
324
325
326
327
Note: See TracBrowser for help on using the repository browser.