1[/
2  Copyright 2006-2007 John Maddock.
3  Distributed under the Boost Software License, Version 1.0.
4  (See accompanying file LICENSE_1_0.txt or copy at
5  http://www.boost.org/LICENSE_1_0.txt).
6]
7
8
9[section:regex_grep regex_grep (Deprecated)]
10
11The algorithm `regex_grep` is deprecated in favor of [regex_iterator]
12which provides a more convenient and standard library friendly interface.
13
14The following documentation is taken unchanged from the previous boost
15release, and will not be updated in future.
16
17   #include <boost/regex.hpp>
18
19`regex_grep` allows you to search through a bidirectional-iterator range and
20locate all the (non-overlapping) matches with a given regular expression.
21The function is declared as:
22
23   template <class Predicate, class iterator, class charT, class traits>
24   unsigned int regex_grep(Predicate foo,
25                           iterator first,
26                           iterator last,
27                           const basic_regex<charT, traits>& e,
28                           boost::match_flag_type flags = match_default)
29
30The library also defines the following convenience versions, which take
31either a `const charT*`, or a `const std::basic_string<>&` in place of a
32pair of iterators.
33
34   template <class Predicate, class charT, class traits>
35   unsigned int regex_grep(Predicate foo,
36               const charT* str,
37               const basic_regex<charT, traits>& e,
38               boost::match_flag_type flags = match_default);
39
40   template <class Predicate, class ST, class SA, class charT, class traits>
41   unsigned int regex_grep(Predicate foo,
42               const std::basic_string<charT, ST, SA>& s,
43               const basic_regex<charT, traits>& e,
44               boost::match_flag_type flags = match_default);
45
46The parameters for the primary version of `regex_grep` have the following meanings:
47
48foo: 	A predicate function object or function pointer, see below for more information.
49
50first: 	The start of the range to search.
51
52last: 	The end of the range to search.
53
54e: 	The regular expression to search for.
55
56flags: 	The flags that determine how matching is carried out, one of the match_flags enumerators.
57
58
59The algorithm finds all of the non-overlapping matches of the expression /e/,
60for each match it fills a `match_results<iterator>` structure, which
61contains information on what matched, and calls the predicate /foo/, passing the
62`match_results<iterator>` as a single argument. If the predicate returns
63/true/, then the grep operation continues, otherwise it terminates
64without searching for further matches. The function returns the number
65of matches found.
66
67The general form of the predicate is:
68
69   struct grep_predicate
70   {
71      bool operator()(const match_results<iterator_type>& m);
72   };
73
74For example the regular expression "a\*b" would find one match in the string
75"aaaaab" and two in the string "aaabb".
76
77Remember this algorithm can be used for a lot more than implementing a
78version of grep, the predicate can be and do anything that you want,
79grep utilities would output the results to the screen, another program could
80index a file based on a regular expression and store a set of bookmarks in a list,
81or a text file conversion utility would output to file. The results of one
82`regex_grep` can even be chained into another `regex_grep` to create recursive parsers.
83
84The algorithm may throw `std::runtime_error` if the complexity of matching the
85expression against an /N/ character string begins to exceed O(N[super 2]), or
86if the program runs out of stack space while matching the expression
87(if Boost.Regex is configured in recursive mode), or if the matcher
88exhausts it's permitted memory allocation (if Boost.Regex is configured in
89non-recursive mode).
90
91Example: convert the example from [regex_search] to use `regex_grep` instead:
92
93   #include <string>
94   #include <map>
95   #include <boost/regex.hpp>
96
97   // IndexClasses:
98   // takes the contents of a file in the form of a string
99   // and searches for all the C++ class definitions, storing
100   // their locations in a map of strings/int's
101   typedef std::map<std::string, int, std::less<std::string> > map_type;
102
103   const char* re =
104      // possibly leading whitespace:
105      "^[[:space:]]*"
106      // possible template declaration:
107      "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
108      // class or struct:
109      "(class|struct)[[:space:]]*"
110      // leading declspec macros etc:
111      "("
112         "\\<\\w+\\>"
113         "("
114            "[[:blank:]]*\\([^)]*\\)"
115         ")?"
116         "[[:space:]]*"
117      ")*"
118      // the class name
119      "(\\<\\w*\\>)[[:space:]]*"
120      // template specialisation parameters
121      "(<[^;:{]+>)?[[:space:]]*"
122      // terminate in { or :
123      "(\\{|:[^;\\{()]*\\{)";
124
125   boost::regex expression(re);
126   class IndexClassesPred
127   {
128      map_type& m;
129      std::string::const_iterator base;
130   public:
131      IndexClassesPred(map_type& a, std::string::const_iterator b) : m(a), base(b) {}
132      bool operator()(const  smatch& what)
133      {
134         // what[0] contains the whole string
135         // what[5] contains the class name.
136         // what[6] contains the template specialisation if any.
137         // add class name and position to map:
138         m[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] =
139                  what[5].first - base;
140         return true;
141      }
142   };
143   void IndexClasses(map_type& m, const std::string& file)
144   {
145      std::string::const_iterator start, end;
146      start = file.begin();
147      end = file.end();
148      regex_grep(IndexClassesPred(m, start), start, end, expression);
149   }
150
151Example: Use `regex_grep` to call a global callback function:
152
153   #include <string>
154   #include <map>
155   #include <boost/regex.hpp>
156
157   // purpose:
158   // takes the contents of a file in the form of a string
159   // and searches for all the C++ class definitions, storing
160   // their locations in a map of strings/int's
161   typedef std::map<std::string, int, std::less<std::string> > map_type;
162
163   const char* re =
164      // possibly leading whitespace:
165      "^[[:space:]]*"
166      // possible template declaration:
167      "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
168      // class or struct:
169      "(class|struct)[[:space:]]*"
170      // leading declspec macros etc:
171      "("
172         "\\<\\w+\\>"
173         "("
174            "[[:blank:]]*\\([^)]*\\)"
175         ")?"
176         "[[:space:]]*"
177      ")*"
178      // the class name
179      "(\\<\\w*\\>)[[:space:]]*"
180      // template specialisation parameters
181      "(<[^;:{]+>)?[[:space:]]*"
182      // terminate in { or :
183      "(\\{|:[^;\\{()]*\\{)";
184
185   boost::regex expression(re);
186   map_type class_index;
187   std::string::const_iterator base;
188
189   bool grep_callback(const  boost::smatch& what)
190   {
191      // what[0] contains the whole string
192      // what[5] contains the class name.
193      // what[6] contains the template specialisation if any.
194      // add class name and position to map:
195      class_index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] =
196                  what[5].first - base;
197      return true;
198   }
199   void IndexClasses(const std::string& file)
200   {
201      std::string::const_iterator start, end;
202      start = file.begin();
203      end = file.end();
204      base = start;
205      regex_grep(grep_callback, start, end, expression, match_default);
206   }
207
208
209Example: use `regex_grep` to call a class member function, use the standard
210library adapters `std::mem_fun` and `std::bind1st` to convert the member
211function into a predicate:
212
213   #include <string>
214   #include <map>
215   #include <boost/regex.hpp>
216   #include <functional>
217   // purpose:
218   // takes the contents of a file in the form of a string
219   // and searches for all the C++ class definitions, storing
220   // their locations in a map of strings/int's
221
222   typedef std::map<std::string, int, std::less<std::string> > map_type;
223   class class_index
224   {
225      boost::regex expression;
226      map_type index;
227      std::string::const_iterator base;
228      bool  grep_callback(boost::smatch what);
229   public:
230      void IndexClasses(const std::string& file);
231      class_index()
232         : index(),
233         expression("^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
234                     "(class|struct)[[:space:]]*(\\<\\w+\\>([[:blank:]]*\\([^)]*\\))?"
235                     "[[:space:]]*)*(\\<\\w*\\>)[[:space:]]*(<[^;:{]+>[[:space:]]*)?"
236                     "(\\{|:[^;\\{()]*\\{)"
237                     ){}
238   };
239   bool  class_index::grep_callback(boost::smatch what)
240   {
241      // what[0] contains the whole string
242      // what[5] contains the class name.
243      // what[6] contains the template specialisation if any.
244      // add class name and position to map:
245      index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] =
246                  what[5].first - base;
247      return true;
248   }
249
250   void class_index::IndexClasses(const std::string& file)
251   {
252      std::string::const_iterator start, end;
253      start = file.begin();
254      end = file.end();
255      base = start;
256      regex_grep(std::bind1st(std::mem_fun(&class_index::grep_callback), this),
257               start,
258               end,
259               expression);
260   }
261
262
263Finally, C++ Builder users can use C++ Builder's closure type as a callback argument:
264
265   #include <string>
266   #include <map>
267   #include <boost/regex.hpp>
268   #include <functional>
269   // purpose:
270   // takes the contents of a file in the form of a string
271   // and searches for all the C++ class definitions, storing
272   // their locations in a map of strings/int's
273
274   typedef std::map<std::string, int, std::less<std::string> > map_type;
275   class class_index
276   {
277      boost::regex expression;
278      map_type index;
279      std::string::const_iterator base;
280      typedef  boost::smatch arg_type;
281      bool grep_callback(const arg_type& what);
282   public:
283      typedef bool (__closure* grep_callback_type)(const arg_type&);
284      void IndexClasses(const std::string& file);
285      class_index()
286         : index(),
287         expression("^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
288                     "(class|struct)[[:space:]]*(\\<\\w+\\>([[:blank:]]*\\([^)]*\\))?"
289                     "[[:space:]]*)*(\\<\\w*\\>)[[:space:]]*(<[^;:{]+>[[:space:]]*)?"
290                     "(\\{|:[^;\\{()]*\\{)"
291                     ){}
292   };
293
294   bool class_index::grep_callback(const arg_type& what)
295   {
296      // what[0] contains the whole string
297   // what[5] contains the class name.
298   // what[6] contains the template specialisation if any.
299   // add class name and position to map:
300   index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] =
301                  what[5].first - base;
302      return true;
303   }
304
305   void class_index::IndexClasses(const std::string& file)
306   {
307      std::string::const_iterator start, end;
308      start = file.begin();
309      end = file.end();
310      base = start;
311      class_index::grep_callback_type cl = &(this->grep_callback);
312      regex_grep(cl,
313               start,
314               end,
315               expression);
316   }
317
318
319[endsect]
320
321