3 * Copyright (c) 1998-2002
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)
13 #pragma warning(disable: 4996 4127)
16 #include <boost/config.hpp>
17 #include <boost/regex.hpp>
18 #include <boost/cregex.hpp>
19 #include <boost/timer.hpp>
20 #include <boost/smart_ptr.hpp>
27 #ifdef BOOST_RE_OLD_IOSTREAM
44 #if defined(_WIN32) && defined(BOOST_REGEX_USE_WIN32_LOCALE)
48 #if (defined(_MSC_VER) && (_MSC_VER <= 1300)) || defined(__sgi)
49 // maybe no Koenig lookup, use using declaration instead:
50 using namespace boost
;
53 #ifndef BOOST_NO_WREGEX
54 ostream
& operator << (ostream
& os
, const std::wstring
& s
)
56 std::wstring::const_iterator i
, j
;
61 os
.put(static_cast<char>(*i
));
69 class string_out_iterator
70 #ifndef BOOST_NO_STD_ITERATOR
71 : public std::iterator
<std::output_iterator_tag
, void, void, void, void>
72 #endif // ndef BOOST_NO_STD_ITERATOR
74 #ifdef BOOST_NO_STD_ITERATOR
75 typedef std::output_iterator_tag iterator_category
;
76 typedef void value_type
;
77 typedef void difference_type
;
79 typedef void reference
;
80 #endif // BOOST_NO_STD_ITERATOR
84 string_out_iterator(S
& s
) : out(&s
) {}
85 string_out_iterator
& operator++() { return *this; }
86 string_out_iterator
& operator++(int) { return *this; }
87 string_out_iterator
& operator*() { return *this; }
88 string_out_iterator
& operator=(typename
S::value_type v
)
96 #if defined(BOOST_MSVC) || (defined(__BORLANDC__) && (__BORLANDC__ == 0x550)) || defined(__SGI_STL_PORT)
98 // problem with std::getline under MSVC6sp3
99 // and C++ Builder 5.5, is this really that hard?
100 istream
& getline(istream
& is
, std::string
& s
)
103 char c
= static_cast<char>(is
.get());
106 BOOST_ASSERT(is
.good());
108 c
= static_cast<char>(is
.get());
113 istream
& getline(istream
& is
, std::string
& s
)
116 if(s
.size() && (s
[s
.size() -1] == '\r'))
117 s
.erase(s
.size() - 1);
124 int main(int argc
, char**argv
)
127 std::istream
* p_in
= &std::cin
;
134 cout
<< "Bad filename: " << argv
[1] << endl
;
141 boost::match_results
<std::string::const_iterator
> sm
;
142 #ifndef BOOST_NO_WREGEX
143 std::wstring ws1
, ws2
;
145 boost::match_results
<std::wstring::const_iterator
> wsm
;
147 boost::match_results
<std::deque
<char>::iterator
> dm
;
148 std::string s1
, s2
, ts
;
151 boost::scoped_array
<boost::regmatch_t
> matches
;
156 unsigned iters
= 100;
157 double wait_time
= (std::min
)(t
.elapsed_min() * 1000, 0.5);
161 cout
<< "Enter expression (or \"quit\" to exit): ";
162 boost::getline(*p_in
, s1
);
164 cout
<< endl
<< s1
<< endl
;
167 #ifndef BOOST_NO_WREGEX
169 std::copy(s1
.begin(), s1
.end(), string_out_iterator
<std::wstring
>(ws1
));
173 #ifndef BOOST_NO_WREGEX
177 catch(std::exception
& e
)
179 cout
<< "Error in expression: \"" << e
.what() << "\"" << endl
;
182 int code
= regcompA(&r
, s1
.c_str(), boost::REG_PERL
);
186 regerrorA(code
, &r
, buf
, 256);
187 cout
<< "regcompA error: \"" << buf
<< "\"" << endl
;
190 nsubs
= r
.re_nsub
+ 1;
191 matches
.reset(new boost::regmatch_t
[nsubs
]);
195 cout
<< "Enter string to search (or \"quit\" to exit): ";
196 boost::getline(*p_in
, s2
);
198 cout
<< endl
<< s2
<< endl
;
202 #ifndef BOOST_NO_WREGEX
204 std::copy(s2
.begin(), s2
.end(), string_out_iterator
<std::wstring
>(ws2
));
206 ds
.erase(ds
.begin(), ds
.end());
207 std::copy(s2
.begin(), s2
.end(), std::back_inserter(ds
));
213 #if defined(_WIN32) && defined(BOOST_REGEX_USE_WIN32_LOCALE)
215 PeekMessage(&msg
, 0, 0, 0, 0);
220 regex_search(s2
, sm
, ex
);
222 // measure time interval for basic_regex<char>
224 iters
*= static_cast<unsigned>((tim
> 0.001) ? (1.1/tim
) : 100);
226 for(i
=0; i
< iters
; ++i
)
228 result
= regex_search(s2
, sm
, ex
);
231 }while(tim
< wait_time
);
233 cout
<< "regex time: " << (tim
* 1000000 / iters
) << "us" << endl
;
236 for(i
= 0; i
< sm
.size(); ++i
)
239 cout
<< "\tmatch " << i
<< ": \"";
241 cout
<< "\" (matched=" << sm
[i
].matched
<< ")" << endl
;
243 cout
<< "\tmatch $`: \"";
244 cout
<< std::string(sm
[-1]);
245 cout
<< "\" (matched=" << sm
[-1].matched
<< ")" << endl
;
246 cout
<< "\tmatch $': \"";
247 cout
<< std::string(sm
[-2]);
248 cout
<< "\" (matched=" << sm
[-2].matched
<< ")" << endl
<< endl
;
251 #ifndef BOOST_NO_WREGEX
252 // measure time interval for boost::wregex
256 regex_search(ws2
, wsm
, wex
);
258 iters
*= static_cast<unsigned>((tim
> 0.001) ? (1.1/tim
) : 100);
260 for(i
= 0; i
< iters
; ++i
)
262 result
= regex_search(ws2
, wsm
, wex
);
265 }while(tim
< wait_time
);
266 cout
<< "wregex time: " << (tim
* 1000000 / iters
) << "us" << endl
;
270 for(i
= 0; i
< wsm
.size(); ++i
)
273 std::copy(wsm
[i
].first
, wsm
[i
].second
, string_out_iterator
<std::wstring
>(tw
));
274 cout
<< "\tmatch " << i
<< ": \"" << tw
;
275 cout
<< "\" (matched=" << sm
[i
].matched
<< ")" << endl
;
277 cout
<< "\tmatch $`: \"";
279 std::copy(wsm
[-1].first
, wsm
[-1].second
, string_out_iterator
<std::wstring
>(tw
));
281 cout
<< "\" (matched=" << sm
[-1].matched
<< ")" << endl
;
282 cout
<< "\tmatch $': \"";
284 std::copy(wsm
[-2].first
, wsm
[-2].second
, string_out_iterator
<std::wstring
>(tw
));
286 cout
<< "\" (matched=" << sm
[-2].matched
<< ")" << endl
<< endl
;
290 // measure time interval for basic_regex<char> using a deque
294 regex_search(ds
.begin(), ds
.end(), dm
, ex
);
296 iters
*= static_cast<unsigned>((tim
> 0.001) ? (1.1/tim
) : 100);
298 for(i
= 0; i
< iters
; ++i
)
300 result
= regex_search(ds
.begin(), ds
.end(), dm
, ex
);
303 }while(tim
< wait_time
);
304 cout
<< "regex time (search over std::deque<char>): " << (tim
* 1000000 / iters
) << "us" << endl
;
308 for(i
= 0; i
< dm
.size(); ++i
)
311 std::copy(dm
[i
].first
, dm
[i
].second
, string_out_iterator
<std::string
>(ts
));
312 cout
<< "\tmatch " << i
<< ": \"" << ts
;
313 cout
<< "\" (matched=" << sm
[i
].matched
<< ")" << endl
;
315 cout
<< "\tmatch $`: \"";
317 std::copy(dm
[-1].first
, dm
[-1].second
, string_out_iterator
<std::string
>(ts
));
319 cout
<< "\" (matched=" << sm
[-1].matched
<< ")" << endl
;
320 cout
<< "\tmatch $': \"";
322 std::copy(dm
[-2].first
, dm
[-2].second
, string_out_iterator
<std::string
>(ts
));
324 cout
<< "\" (matched=" << sm
[-2].matched
<< ")" << endl
<< endl
;
327 // measure time interval for POSIX matcher:
331 regexecA(&r
, s2
.c_str(), nsubs
, matches
.get(), 0);
333 iters
*= static_cast<unsigned>((tim
> 0.001) ? (1.1/tim
) : 100);
335 for(i
= 0; i
< iters
; ++i
)
337 result
= regexecA(&r
, s2
.c_str(), nsubs
, matches
.get(), 0);
340 }while(tim
< wait_time
);
341 cout
<< "POSIX regexecA time: " << (tim
* 1000000 / iters
) << "us" << endl
;
345 for(i
= 0; i
< nsubs
; ++i
)
347 if(matches
[i
].rm_so
>= 0)
349 ts
.assign(s2
.begin() + matches
[i
].rm_so
, s2
.begin() + matches
[i
].rm_eo
);
350 cout
<< "\tmatch " << i
<< ": \"" << ts
<< "\" (matched=" << (matches
[i
].rm_so
!= -1) << ")"<< endl
;
353 cout
<< "\tmatch " << i
<< ": \"\" (matched=" << (matches
[i
].rm_so
!= -1) << ")" << endl
; // no match
355 cout
<< "\tmatch $`: \"";
357 ts
.assign(s2
.begin(), s2
.begin() + matches
[0].rm_so
);
359 cout
<< "\" (matched=" << (matches
[0].rm_so
!= 0) << ")" << endl
;
360 cout
<< "\tmatch $': \"";
362 ts
.assign(s2
.begin() + matches
[0].rm_eo
, s2
.end());
364 cout
<< "\" (matched=" << (matches
[0].rm_eo
!= (int)s2
.size()) << ")" << endl
<< endl
;
373 #if defined(_WIN32) && defined(BOOST_REGEX_USE_WIN32_LOCALE) && !defined(UNDER_CE)
374 #pragma comment(lib, "user32.lib")