Ticket #1627: grep.2.hpp

File grep.2.hpp, 2.8 KB (added by Emre Turkay <emreturkay@…>, 15 years ago)

The one with the workaround for VC.

Line 
1#ifndef BOOST_IOSTREAMS_GREP_HPP_INCLUDED
2#define BOOST_IOSTREAMS_GREP_HPP_INCLUDED
3
4#include <string>
5#include <boost/regex.hpp>
6#include <boost/iostreams/categories.hpp>
7#include <boost/iostreams/operations.hpp>
8
9namespace boost { namespace iostreams {
10
11template <typename Ch>
12struct basic_grep_filter
13{
14 typedef Ch char_type;
15 struct category: dual_use, filter_tag { };
16
17 typedef char_traits<char_type> traits_type;
18 typedef std::basic_string<char_type> string_type;
19 typedef boost::basic_regex<char_type> regex_type;
20
21 explicit basic_grep_filter(const char* expr)
22 : expr_(expr), eof_(false), eol_(true), iter_(line_.end())
23 {
24 };
25
26 template <typename Source>
27 typename traits_type::int_type get(Source& src)
28 {
29 if (eof_ && eol_)
30 return EOF;
31
32 if (!eol_)
33 return next();
34
35 for (;;)
36 {
37 typename traits_type::int_type c = iostreams::get(src);
38
39 if (c == traits_type::would_block())
40 return c;
41
42 line_ += c;
43 eol_ = false;
44
45 if (traits_type::is_eof(c))
46 {
47 eof_ = true;
48 if (boost::regex_search(line_, expr_))
49 {
50 iter_ = line_.begin();
51 return next();
52 }
53
54 line_.erase();
55 eol_ = true;
56 return c;
57 }
58
59 if (c == traits_type::newline())
60 {
61 if (boost::regex_search(line_, expr_))
62 {
63 iter_ = line_.begin();
64 return next();
65 }
66
67 line_.erase();
68 eol_ = true;
69 }
70 }
71 }
72
73 template <typename Sink>
74 bool put(Sink& snk, char_type c)
75 {
76 if (!traits_type::is_eof(c))
77 line_ += c;
78
79 if (traits_type::is_eof(c) || (c == traits_type::newline()))
80 {
81 if (boost::regex_search(line_, expr_))
82 std::for_each(line_.begin(), line_.end(), writer<Sink>(snk));
83
84 if (traits_type::is_eof(c))
85 iostreams::put(snk, c);
86
87 line_.erase();
88 }
89
90 return true;
91 }
92
93private:
94 char_type next()
95 {
96 char_type c = *iter_;
97 ++iter_;
98 if (iter_ == line_.end())
99 {
100 line_.erase();
101 eol_ = true;
102 }
103 return c;
104 }
105
106 template <typename Sink>
107 struct writer
108 {
109 writer(Sink& snk): snk_(snk) { }
110
111 void operator()(const char_type& c)
112 {
113 iostreams::put(snk_, c);
114 }
115
116 private:
117 Sink& snk_;
118 };
119
120private:
121 regex_type expr_;
122 bool eof_;
123 bool eol_;
124 string_type line_;
125 typename string_type::const_iterator iter_;
126};
127
128typedef basic_grep_filter<char> grep_filter;
129typedef basic_grep_filter<wchar_t> wgrep_filter;
130
131} } // End namespaces iostreams, boost.
132
133#endif //#ifndef BOOST_IOSTREAMS_GREP_HPP_INCLUDED