1 /*
2  *
3  * Copyright (c) 1998-2002
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_grep.hpp
15   *   VERSION      see <boost/version.hpp>
16   *   DESCRIPTION: Provides regex_grep implementation.
17   */
18 
19 #ifndef BOOST_REGEX_V5_REGEX_GREP_HPP
20 #define BOOST_REGEX_V5_REGEX_GREP_HPP
21 
22 
23 namespace boost{
24 
25 //
26 // regex_grep:
27 // find all non-overlapping matches within the sequence first last:
28 //
29 template <class Predicate, class BidiIterator, class charT, class traits>
regex_grep(Predicate foo,BidiIterator first,BidiIterator last,const basic_regex<charT,traits> & e,match_flag_type flags=match_default)30 inline unsigned int regex_grep(Predicate foo,
31                                BidiIterator first,
32                                BidiIterator last,
33                                const basic_regex<charT, traits>& e,
34                                match_flag_type flags = match_default)
35 {
36    if(e.flags() & regex_constants::failbit)
37       return false;
38 
39    typedef typename match_results<BidiIterator>::allocator_type match_allocator_type;
40 
41    match_results<BidiIterator> m;
42    BOOST_REGEX_DETAIL_NS::perl_matcher<BidiIterator, match_allocator_type, traits> matcher(first, last, m, e, flags, first);
43    unsigned int count = 0;
44    while(matcher.find())
45    {
46       ++count;
47       if(0 == foo(m))
48          return count; // caller doesn't want to go on
49       if(m[0].second == last)
50          return count; // we've reached the end, don't try and find an extra null match.
51       if(m.length() == 0)
52       {
53          if(m[0].second == last)
54             return count;
55          // we found a NULL-match, now try to find
56          // a non-NULL one at the same position:
57          match_results<BidiIterator, match_allocator_type> m2(m);
58          matcher.setf(match_not_null | match_continuous);
59          if(matcher.find())
60          {
61             ++count;
62             if(0 == foo(m))
63                return count;
64          }
65          else
66          {
67             // reset match back to where it was:
68             m = m2;
69          }
70          matcher.unsetf((match_not_null | match_continuous) & ~flags);
71       }
72    }
73    return count;
74 }
75 
76 //
77 // regex_grep convenience interfaces:
78 //
79 template <class Predicate, class charT, class traits>
regex_grep(Predicate foo,const charT * str,const basic_regex<charT,traits> & e,match_flag_type flags=match_default)80 inline unsigned int regex_grep(Predicate foo, const charT* str,
81                         const basic_regex<charT, traits>& e,
82                         match_flag_type flags = match_default)
83 {
84    return regex_grep(foo, str, str + traits::length(str), e, flags);
85 }
86 
87 template <class Predicate, class ST, class SA, class charT, class traits>
regex_grep(Predicate foo,const std::basic_string<charT,ST,SA> & s,const basic_regex<charT,traits> & e,match_flag_type flags=match_default)88 inline unsigned int regex_grep(Predicate foo, const std::basic_string<charT, ST, SA>& s,
89                  const basic_regex<charT, traits>& e,
90                  match_flag_type flags = match_default)
91 {
92    return regex_grep(foo, s.begin(), s.end(), e, flags);
93 }
94 
95 } // namespace boost
96 
97 #endif  // BOOST_REGEX_V5_REGEX_GREP_HPP
98 
99