]> git.lyx.org Git - lyx.git/blob - boost/boost/regex/v4/regex_iterator.hpp
Update to latest from boost 1.34.x branch
[lyx.git] / boost / boost / regex / v4 / regex_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         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_HAS_ABI_HEADERS
27 #  include BOOST_ABI_PREFIX
28 #endif
29
30 template <class BidirectionalIterator, 
31           class charT,
32           class traits>
33 class regex_iterator_implementation 
34 {
35    typedef basic_regex<charT, traits> regex_type;
36
37    match_results<BidirectionalIterator> what;  // current match
38    BidirectionalIterator                base;  // start of sequence
39    BidirectionalIterator                end;   // end of sequence
40    const regex_type                     re;   // the expression
41    match_flag_type                      flags; // flags for matching
42
43 public:
44    regex_iterator_implementation(const regex_type* p, BidirectionalIterator last, match_flag_type f)
45       : base(), end(last), re(*p), flags(f){}
46    bool init(BidirectionalIterator first)
47    {
48       base = first;
49       return regex_search(first, end, what, re, flags);
50    }
51    bool compare(const regex_iterator_implementation& that)
52    {
53       if(this == &that) return true;
54       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);
55    }
56    const match_results<BidirectionalIterator>& get()
57    { return what; }
58    bool next()
59    {
60       //if(what.prefix().first != what[0].second)
61       //   flags |= match_prev_avail;
62       BidirectionalIterator next_start = what[0].second;
63       match_flag_type f(flags);
64       if(!what.length())
65          f |= regex_constants::match_not_initial_null;
66       //if(base != next_start)
67       //   f |= regex_constants::match_not_bob;
68       bool result = regex_search(next_start, end, what, re, f, base);
69       if(result)
70          what.set_base(base);
71       return result;
72    }
73 private:
74    regex_iterator_implementation& operator=(const regex_iterator_implementation&);
75 };
76
77 template <class BidirectionalIterator, 
78           class charT = BOOST_DEDUCED_TYPENAME re_detail::regex_iterator_traits<BidirectionalIterator>::value_type,
79           class traits = regex_traits<charT> >
80 class regex_iterator 
81 #ifndef BOOST_NO_STD_ITERATOR
82    : public std::iterator<
83          std::forward_iterator_tag, 
84          match_results<BidirectionalIterator>,
85          typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type,
86          const match_results<BidirectionalIterator>*,
87          const match_results<BidirectionalIterator>& >         
88 #endif
89 {
90 private:
91    typedef regex_iterator_implementation<BidirectionalIterator, charT, traits> impl;
92    typedef shared_ptr<impl> pimpl;
93 public:
94    typedef          basic_regex<charT, traits>                   regex_type;
95    typedef          match_results<BidirectionalIterator>                    value_type;
96    typedef typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type 
97                                                                             difference_type;
98    typedef          const value_type*                                       pointer;
99    typedef          const value_type&                                       reference; 
100    typedef          std::forward_iterator_tag                               iterator_category;
101    
102    regex_iterator(){}
103    regex_iterator(BidirectionalIterator a, BidirectionalIterator b, 
104                   const regex_type& re, 
105                   match_flag_type m = match_default)
106                   : pdata(new impl(&re, b, m))
107    {
108       if(!pdata->init(a))
109       {
110          pdata.reset();
111       }
112    }
113    regex_iterator(const regex_iterator& that)
114       : pdata(that.pdata) {}
115    regex_iterator& operator=(const regex_iterator& that)
116    {
117       pdata = that.pdata;
118       return *this;
119    }
120    bool operator==(const regex_iterator& that)const
121    { 
122       if((pdata.get() == 0) || (that.pdata.get() == 0))
123          return pdata.get() == that.pdata.get();
124       return pdata->compare(*(that.pdata.get())); 
125    }
126    bool operator!=(const regex_iterator& that)const
127    { return !(*this == that); }
128    const value_type& operator*()const
129    { return pdata->get(); }
130    const value_type* operator->()const
131    { return &(pdata->get()); }
132    regex_iterator& operator++()
133    {
134       cow();
135       if(0 == pdata->next())
136       {
137          pdata.reset();
138       }
139       return *this;
140    }
141    regex_iterator operator++(int)
142    {
143       regex_iterator result(*this);
144       ++(*this);
145       return result;
146    }
147 private:
148
149    pimpl pdata;
150
151    void cow()
152    {
153       // copy-on-write
154       if(pdata.get() && !pdata.unique())
155       {
156          pdata.reset(new impl(*(pdata.get())));
157       }
158    }
159 };
160
161 typedef regex_iterator<const char*> cregex_iterator;
162 typedef regex_iterator<std::string::const_iterator> sregex_iterator;
163 #ifndef BOOST_NO_WREGEX
164 typedef regex_iterator<const wchar_t*> wcregex_iterator;
165 typedef regex_iterator<std::wstring::const_iterator> wsregex_iterator;
166 #endif
167
168 // make_regex_iterator:
169 template <class charT, class traits>
170 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)
171 {
172    return regex_iterator<const charT*, charT, traits>(p, p+traits::length(p), e, m);
173 }
174 template <class charT, class traits, class ST, class SA>
175 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)
176 {
177    return regex_iterator<typename std::basic_string<charT, ST, SA>::const_iterator, charT, traits>(p.begin(), p.end(), e, m);
178 }
179
180 #ifdef BOOST_HAS_ABI_HEADERS
181 #  include BOOST_ABI_SUFFIX
182 #endif
183
184 } // namespace boost
185
186 #endif // BOOST_REGEX_V4_REGEX_ITERATOR_HPP
187