]> git.lyx.org Git - features.git/blob - boost/boost/regex/v4/u32regex_token_iterator.hpp
boost: add eol property
[features.git] / boost / boost / regex / v4 / u32regex_token_iterator.hpp
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         u32regex_token_iterator.hpp
15   *   VERSION      see <boost/version.hpp>
16   *   DESCRIPTION: Provides u32regex_token_iterator implementation.
17   */
18
19 #ifndef BOOST_REGEX_V4_U32REGEX_TOKEN_ITERATOR_HPP
20 #define BOOST_REGEX_V4_U32REGEX_TOKEN_ITERATOR_HPP
21
22 #if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\
23       || BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
24       || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
25 //
26 // Borland C++ Builder 6, and Visual C++ 6,
27 // can't cope with the array template constructor
28 // so we have a template member that will accept any type as 
29 // argument, and then assert that is really is an array:
30 //
31 #include <boost/static_assert.hpp>
32 #include <boost/type_traits/is_array.hpp>
33 #endif
34
35 namespace boost{
36
37 #ifdef BOOST_HAS_ABI_HEADERS
38 #  include BOOST_ABI_PREFIX
39 #endif
40 #if BOOST_WORKAROUND(BOOST_MSVC, > 1300)
41 #  pragma warning(push)
42 #  pragma warning(disable:4700)
43 #endif
44
45 template <class BidirectionalIterator>
46 class u32regex_token_iterator_implementation 
47 {
48    typedef u32regex                              regex_type;
49    typedef sub_match<BidirectionalIterator>      value_type;
50
51    match_results<BidirectionalIterator> what;   // current match
52    BidirectionalIterator                end;    // end of search area
53    BidirectionalIterator                base;   // start of search area
54    const regex_type                     re;     // the expression
55    match_flag_type                      flags;  // match flags
56    value_type                           result; // the current string result
57    int                                  N;      // the current sub-expression being enumerated
58    std::vector<int>                     subs;   // the sub-expressions to enumerate
59
60 public:
61    u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, int sub, match_flag_type f)
62       : end(last), re(*p), flags(f){ subs.push_back(sub); }
63    u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const std::vector<int>& v, match_flag_type f)
64       : end(last), re(*p), flags(f), subs(v){}
65 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
66       // can't reliably get this to work....
67 #elif (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\
68       || BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
69       || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) \
70       || BOOST_WORKAROUND(__HP_aCC, < 60700)
71    template <class T>
72    u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const T& submatches, match_flag_type f)
73       : end(last), re(*p), flags(f)
74    {
75       // assert that T really is an array:
76       BOOST_STATIC_ASSERT(::boost::is_array<T>::value);
77       const std::size_t array_size = sizeof(T) / sizeof(submatches[0]);
78       for(std::size_t i = 0; i < array_size; ++i)
79       {
80          subs.push_back(submatches[i]);
81       }
82    }
83 #else
84    template <std::size_t CN>
85    u32regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const int (&submatches)[CN], match_flag_type f)
86       : end(last), re(*p), flags(f)
87    {
88       for(std::size_t i = 0; i < CN; ++i)
89       {
90          subs.push_back(submatches[i]);
91       }
92    }
93 #endif
94
95    bool init(BidirectionalIterator first)
96    {
97       base = first;
98       N = 0;
99       if(u32regex_search(first, end, what, re, flags, base) == true)
100       {
101          N = 0;
102          result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]);
103          return true;
104       }
105       else if((subs[N] == -1) && (first != end))
106       {
107          result.first = first;
108          result.second = end;
109          result.matched = (first != end);
110          N = -1;
111          return true;
112       }
113       return false;
114    }
115    bool compare(const u32regex_token_iterator_implementation& that)
116    {
117       if(this == &that) return true;
118       return (&re.get_data() == &that.re.get_data()) 
119          && (end == that.end) 
120          && (flags == that.flags) 
121          && (N == that.N) 
122          && (what[0].first == that.what[0].first) 
123          && (what[0].second == that.what[0].second);
124    }
125    const value_type& get()
126    { return result; }
127    bool next()
128    {
129       if(N == -1)
130          return false;
131       if(N+1 < (int)subs.size())
132       {
133          ++N;
134          result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
135          return true;
136       }
137       //if(what.prefix().first != what[0].second)
138       //   flags |= match_prev_avail | regex_constants::match_not_bob;
139       BidirectionalIterator last_end(what[0].second);
140       if(u32regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags), base))
141       {
142          N =0;
143          result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
144          return true;
145       }
146       else if((last_end != end) && (subs[0] == -1))
147       {
148          N =-1;
149          result.first = last_end;
150          result.second = end;
151          result.matched = (last_end != end);
152          return true;
153       }
154       return false;
155    }
156 private:
157    u32regex_token_iterator_implementation& operator=(const u32regex_token_iterator_implementation&);
158 };
159
160 template <class BidirectionalIterator>
161 class u32regex_token_iterator 
162 #ifndef BOOST_NO_STD_ITERATOR
163    : public std::iterator<
164          std::forward_iterator_tag, 
165          sub_match<BidirectionalIterator>,
166          typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type,
167          const sub_match<BidirectionalIterator>*,
168          const sub_match<BidirectionalIterator>& >         
169 #endif
170 {
171 private:
172    typedef u32regex_token_iterator_implementation<BidirectionalIterator> impl;
173    typedef shared_ptr<impl> pimpl;
174 public:
175    typedef          u32regex                                                regex_type;
176    typedef          sub_match<BidirectionalIterator>                        value_type;
177    typedef typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type 
178                                                                             difference_type;
179    typedef          const value_type*                                       pointer;
180    typedef          const value_type&                                       reference; 
181    typedef          std::forward_iterator_tag                               iterator_category;
182    
183    u32regex_token_iterator(){}
184    u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, 
185                         int submatch = 0, match_flag_type m = match_default)
186                         : pdata(new impl(&re, b, submatch, m))
187    {
188       if(!pdata->init(a))
189          pdata.reset();
190    }
191    u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, 
192                         const std::vector<int>& submatches, match_flag_type m = match_default)
193                         : pdata(new impl(&re, b, submatches, m))
194    {
195       if(!pdata->init(a))
196          pdata.reset();
197    }
198 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
199       // can't reliably get this to work....
200 #elif (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\
201       || BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
202       || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) \
203       || BOOST_WORKAROUND(__HP_aCC, < 60700)
204    template <class T>
205    u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
206                         const T& submatches, match_flag_type m = match_default)
207                         : pdata(new impl(&re, b, submatches, m))
208    {
209       if(!pdata->init(a))
210          pdata.reset();
211    }
212 #else
213    template <std::size_t N>
214    u32regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
215                         const int (&submatches)[N], match_flag_type m = match_default)
216                         : pdata(new impl(&re, b, submatches, m))
217    {
218       if(!pdata->init(a))
219          pdata.reset();
220    }
221 #endif
222    u32regex_token_iterator(const u32regex_token_iterator& that)
223       : pdata(that.pdata) {}
224    u32regex_token_iterator& operator=(const u32regex_token_iterator& that)
225    {
226       pdata = that.pdata;
227       return *this;
228    }
229    bool operator==(const u32regex_token_iterator& that)const
230    { 
231       if((pdata.get() == 0) || (that.pdata.get() == 0))
232          return pdata.get() == that.pdata.get();
233       return pdata->compare(*(that.pdata.get())); 
234    }
235    bool operator!=(const u32regex_token_iterator& that)const
236    { return !(*this == that); }
237    const value_type& operator*()const
238    { return pdata->get(); }
239    const value_type* operator->()const
240    { return &(pdata->get()); }
241    u32regex_token_iterator& operator++()
242    {
243       cow();
244       if(0 == pdata->next())
245       {
246          pdata.reset();
247       }
248       return *this;
249    }
250    u32regex_token_iterator operator++(int)
251    {
252       u32regex_token_iterator result(*this);
253       ++(*this);
254       return result;
255    }
256 private:
257
258    pimpl pdata;
259
260    void cow()
261    {
262       // copy-on-write
263       if(pdata.get() && !pdata.unique())
264       {
265          pdata.reset(new impl(*(pdata.get())));
266       }
267    }
268 };
269
270 typedef u32regex_token_iterator<const char*> utf8regex_token_iterator;
271 typedef u32regex_token_iterator<const UChar*> utf16regex_token_iterator;
272 typedef u32regex_token_iterator<const UChar32*> utf32regex_token_iterator;
273
274 // construction from an integral sub_match state_id:
275 inline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
276 {
277    return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);
278 }
279 #ifndef BOOST_NO_WREGEX
280 inline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
281 {
282    return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);
283 }
284 #endif
285 #if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)
286 inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
287 {
288    return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);
289 }
290 #endif
291 template <class charT, class Traits, class Alloc>
292 inline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
293 {
294    typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;
295    return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, m);
296 }
297 inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UnicodeString& s, const u32regex& e, int submatch = 0, regex_constants::match_flag_type m = regex_constants::match_default)
298 {
299    return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);
300 }
301
302 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
303 // construction from a reference to an array:
304 template <std::size_t N>
305 inline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
306 {
307    return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);
308 }
309 #ifndef BOOST_NO_WREGEX
310 template <std::size_t N>
311 inline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
312 {
313    return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);
314 }
315 #endif
316 #if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)
317 template <std::size_t N>
318 inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
319 {
320    return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, m);
321 }
322 #endif
323 template <class charT, class Traits, class Alloc, std::size_t N>
324 inline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
325 {
326    typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;
327    return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, m);
328 }
329 template <std::size_t N>
330 inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UnicodeString& s, const u32regex& e, const int (&submatch)[N], regex_constants::match_flag_type m = regex_constants::match_default)
331 {
332    return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);
333 }
334 #endif // BOOST_MSVC < 1300
335
336 // construction from a vector of sub_match state_id's:
337 inline u32regex_token_iterator<const char*> make_u32regex_token_iterator(const char* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
338 {
339    return u32regex_token_iterator<const char*>(p, p+std::strlen(p), e, submatch, m);
340 }
341 #ifndef BOOST_NO_WREGEX
342 inline u32regex_token_iterator<const wchar_t*> make_u32regex_token_iterator(const wchar_t* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
343 {
344    return u32regex_token_iterator<const wchar_t*>(p, p+std::wcslen(p), e, submatch, m);
345 }
346 #endif
347 #if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)
348 inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UChar* p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
349 {
350    return u32regex_token_iterator<const UChar*>(p, p+u_strlen(p), e, submatch, m);
351 }
352 #endif
353 template <class charT, class Traits, class Alloc>
354 inline u32regex_token_iterator<typename std::basic_string<charT, Traits, Alloc>::const_iterator> make_u32regex_token_iterator(const std::basic_string<charT, Traits, Alloc>& p, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
355 {
356    typedef typename std::basic_string<charT, Traits, Alloc>::const_iterator iter_type;
357    return u32regex_token_iterator<iter_type>(p.begin(), p.end(), e, m);
358 }
359 inline u32regex_token_iterator<const UChar*> make_u32regex_token_iterator(const UnicodeString& s, const u32regex& e, const std::vector<int>& submatch, regex_constants::match_flag_type m = regex_constants::match_default)
360 {
361    return u32regex_token_iterator<const UChar*>(s.getBuffer(), s.getBuffer() + s.length(), e, submatch, m);
362 }
363
364 #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
365 #  pragma warning(pop)
366 #endif
367 #ifdef BOOST_HAS_ABI_HEADERS
368 #  include BOOST_ABI_SUFFIX
369 #endif
370
371 } // namespace boost
372
373 #endif // BOOST_REGEX_V4_REGEX_TOKEN_ITERATOR_HPP
374
375
376
377