[/ 
  Copyright 2006-2007 John Maddock.
  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE_1_0.txt or copy at
  http://www.boost.org/LICENSE_1_0.txt).
]


[section:regex_grep regex_grep (Deprecated)]

The algorithm `regex_grep` is deprecated in favor of [regex_iterator]
which provides a more convenient and standard library friendly interface.

The following documentation is taken unchanged from the previous boost 
release, and will not be updated in future.

   #include <boost/regex.hpp>

`regex_grep` allows you to search through a bidirectional-iterator range and 
locate all the (non-overlapping) matches with a given regular expression. 
The function is declared as:

   template <class Predicate, class iterator, class charT, class traits>
   unsigned int regex_grep(Predicate foo,
                           iterator first,
                           iterator last,
                           const basic_regex<charT, traits>& e,
                           boost::match_flag_type flags = match_default)

The library also defines the following convenience versions, which take 
either a `const charT*`, or a `const std::basic_string<>&` in place of a 
pair of iterators.

   template <class Predicate, class charT, class traits>
   unsigned int regex_grep(Predicate foo, 
               const charT* str, 
               const basic_regex<charT, traits>& e, 
               boost::match_flag_type flags = match_default);

   template <class Predicate, class ST, class SA, class charT, class traits>
   unsigned int regex_grep(Predicate foo, 
               const std::basic_string<charT, ST, SA>& s, 
               const basic_regex<charT, traits>& e, 
               boost::match_flag_type flags = match_default);

The parameters for the primary version of `regex_grep` have the following meanings: 

foo: 	A predicate function object or function pointer, see below for more information.
 	 
first: 	The start of the range to search. 	 

last: 	The end of the range to search. 	 

e: 	The regular expression to search for. 	 

flags: 	The flags that determine how matching is carried out, one of the match_flags enumerators. 	 


The algorithm finds all of the non-overlapping matches of the expression /e/, 
for each match it fills a `match_results<iterator>` structure, which 
contains information on what matched, and calls the predicate /foo/, passing the 
`match_results<iterator>` as a single argument. If the predicate returns 
/true/, then the grep operation continues, otherwise it terminates 
without searching for further matches. The function returns the number 
of matches found.

The general form of the predicate is:

   struct grep_predicate
   {
      bool operator()(const match_results<iterator_type>& m);
   };

For example the regular expression "a\*b" would find one match in the string 
"aaaaab" and two in the string "aaabb".

Remember this algorithm can be used for a lot more than implementing a 
version of grep, the predicate can be and do anything that you want, 
grep utilities would output the results to the screen, another program could 
index a file based on a regular expression and store a set of bookmarks in a list, 
or a text file conversion utility would output to file. The results of one 
`regex_grep` can even be chained into another `regex_grep` to create recursive parsers.

The algorithm may throw `std::runtime_error` if the complexity of matching the 
expression against an /N/ character string begins to exceed O(N[super 2]), or 
if the program runs out of stack space while matching the expression 
(if Boost.Regex is configured in recursive mode), or if the matcher 
exhausts it's permitted memory allocation (if Boost.Regex is configured in 
non-recursive mode).

Example: convert the example from [regex_search] to use `regex_grep` instead:

   #include <string> 
   #include <map> 
   #include <boost/regex.hpp> 

   // IndexClasses: 
   // takes the contents of a file in the form of a string 
   // and searches for all the C++ class definitions, storing 
   // their locations in a map of strings/int's 
   typedef std::map<std::string, int, std::less<std::string> > map_type; 

   const char* re = 
      // possibly leading whitespace:   
      "^[[:space:]]*" 
      // possible template declaration:
      "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
      // class or struct:
      "(class|struct)[[:space:]]*" 
      // leading declspec macros etc:
      "("
         "\\<\\w+\\>"
         "("
            "[[:blank:]]*\\([^)]*\\)"
         ")?"
         "[[:space:]]*"
      ")*" 
      // the class name
      "(\\<\\w*\\>)[[:space:]]*" 
      // template specialisation parameters
      "(<[^;:{]+>)?[[:space:]]*"
      // terminate in { or :
      "(\\{|:[^;\\{()]*\\{)";

   boost::regex expression(re); 
   class IndexClassesPred 
   { 
      map_type& m; 
      std::string::const_iterator base; 
   public: 
      IndexClassesPred(map_type& a, std::string::const_iterator b) : m(a), base(b) {} 
      bool operator()(const  smatch& what) 
      { 
         // what[0] contains the whole string 
         // what[5] contains the class name. 
         // what[6] contains the template specialisation if any. 
         // add class name and position to map: 
         m[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] = 
                  what[5].first - base; 
         return true; 
      } 
   }; 
   void IndexClasses(map_type& m, const std::string& file) 
   { 
      std::string::const_iterator start, end; 
      start = file.begin(); 
      end = file.end(); 
      regex_grep(IndexClassesPred(m, start), start, end, expression); 
   }

Example: Use `regex_grep` to call a global callback function:

   #include <string> 
   #include <map> 
   #include <boost/regex.hpp> 

   // purpose: 
   // takes the contents of a file in the form of a string 
   // and searches for all the C++ class definitions, storing 
   // their locations in a map of strings/int's 
   typedef std::map<std::string, int, std::less<std::string> > map_type; 

   const char* re = 
      // possibly leading whitespace:   
      "^[[:space:]]*" 
      // possible template declaration:
      "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
      // class or struct:
      "(class|struct)[[:space:]]*" 
      // leading declspec macros etc:
      "("
         "\\<\\w+\\>"
         "("
            "[[:blank:]]*\\([^)]*\\)"
         ")?"
         "[[:space:]]*"
      ")*" 
      // the class name
      "(\\<\\w*\\>)[[:space:]]*" 
      // template specialisation parameters
      "(<[^;:{]+>)?[[:space:]]*"
      // terminate in { or :
      "(\\{|:[^;\\{()]*\\{)";

   boost::regex expression(re);
   map_type class_index; 
   std::string::const_iterator base; 

   bool grep_callback(const  boost::smatch& what) 
   { 
      // what[0] contains the whole string 
      // what[5] contains the class name. 
      // what[6] contains the template specialisation if any. 
      // add class name and position to map: 
      class_index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] = 
                  what[5].first - base; 
      return true; 
   } 
   void IndexClasses(const std::string& file) 
   { 
      std::string::const_iterator start, end; 
      start = file.begin(); 
      end = file.end(); 
      base = start; 
      regex_grep(grep_callback, start, end, expression, match_default); 
   }
 

Example: use `regex_grep` to call a class member function, use the standard 
library adapters `std::mem_fun` and `std::bind1st` to convert the member 
function into a predicate:

   #include <string> 
   #include <map> 
   #include <boost/regex.hpp> 
   #include <functional> 
   // purpose: 
   // takes the contents of a file in the form of a string 
   // and searches for all the C++ class definitions, storing 
   // their locations in a map of strings/int's 

   typedef std::map<std::string, int, std::less<std::string> > map_type; 
   class class_index 
   { 
      boost::regex expression; 
      map_type index; 
      std::string::const_iterator base; 
      bool  grep_callback(boost::smatch what); 
   public: 
      void IndexClasses(const std::string& file); 
      class_index() 
         : index(), 
         expression("^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" 
                     "(class|struct)[[:space:]]*(\\<\\w+\\>([[:blank:]]*\\([^)]*\\))?" 
                     "[[:space:]]*)*(\\<\\w*\\>)[[:space:]]*(<[^;:{]+>[[:space:]]*)?" 
                     "(\\{|:[^;\\{()]*\\{)" 
                     ){} 
   }; 
   bool  class_index::grep_callback(boost::smatch what) 
   { 
      // what[0] contains the whole string 
      // what[5] contains the class name. 
      // what[6] contains the template specialisation if any. 
      // add class name and position to map: 
      index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] = 
                  what[5].first - base; 
      return true; 
   } 

   void class_index::IndexClasses(const std::string& file) 
   { 
      std::string::const_iterator start, end; 
      start = file.begin(); 
      end = file.end(); 
      base = start; 
      regex_grep(std::bind1st(std::mem_fun(&class_index::grep_callback), this), 
               start, 
               end, 
               expression); 
   } 
 

Finally, C++ Builder users can use C++ Builder's closure type as a callback argument:

   #include <string> 
   #include <map> 
   #include <boost/regex.hpp> 
   #include <functional> 
   // purpose: 
   // takes the contents of a file in the form of a string 
   // and searches for all the C++ class definitions, storing 
   // their locations in a map of strings/int's 

   typedef std::map<std::string, int, std::less<std::string> > map_type; 
   class class_index 
   { 
      boost::regex expression; 
      map_type index; 
      std::string::const_iterator base; 
      typedef  boost::smatch arg_type; 
      bool grep_callback(const arg_type& what); 
   public: 
      typedef bool (__closure* grep_callback_type)(const arg_type&); 
      void IndexClasses(const std::string& file); 
      class_index() 
         : index(), 
         expression("^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" 
                     "(class|struct)[[:space:]]*(\\<\\w+\\>([[:blank:]]*\\([^)]*\\))?" 
                     "[[:space:]]*)*(\\<\\w*\\>)[[:space:]]*(<[^;:{]+>[[:space:]]*)?" 
                     "(\\{|:[^;\\{()]*\\{)" 
                     ){} 
   }; 

   bool class_index::grep_callback(const arg_type& what) 
   { 
      // what[0] contains the whole string    
   // what[5] contains the class name.    
   // what[6] contains the template specialisation if any.    
   // add class name and position to map:    
   index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] = 
                  what[5].first - base; 
      return true; 
   } 

   void class_index::IndexClasses(const std::string& file) 
   { 
      std::string::const_iterator start, end; 
      start = file.begin(); 
      end = file.end(); 
      base = start; 
      class_index::grep_callback_type cl = &(this->grep_callback); 
      regex_grep(cl, 
               start, 
               end, 
               expression); 
   }


[endsect]

