Commit 9f0d9611 by Tim Shen Committed by Tim Shen

regex.h: Remove unnecessary friends.

2013-10-26  Tim Shen  <timshen91@gmail.com>

	* include/bits/regex.h: Remove unnecessary friends.
	* include/bits/regex.tcc (__regex_algo_impl<>): Move __get_executor
	to here.
	* include/bits/regex_executor.h: Remove _DFSExecutor and _BFSExecutor;
	they are merged into _Executor. Eliminate quantifier tracking part, so
	it's faster.
	* include/bits/regex_executor.tcc: Implement _Executor.
	* testsuite/28_regex/algorithms/regex_match/ecma/char/ungreedy.cc: New.
	* testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc: Adjust
	duplicate testcases.
	* testsuite/performance/28_regex/split.h: New.
	* testsuite/performance/28_regex/split_bfs.cc: New.
	* testsuite/util/testsuite_regex.h: Adjust behavior of two-executors
	agreement judger: do not compare match_results when executor return
	false.

From-SVN: r204093
parent 5d905bb6
2013-10-26 Tim Shen <timshen91@gmail.com>
* include/bits/regex.h: Remove unnecessary friends.
* include/bits/regex.tcc (__regex_algo_impl<>): Move __get_executor
to here.
* include/bits/regex_executor.h: Remove _DFSExecutor and _BFSExecutor;
they are merged into _Executor. Eliminate quantifier tracking part, so
it's faster.
* include/bits/regex_executor.tcc: Implement _Executor.
* testsuite/28_regex/algorithms/regex_match/ecma/char/ungreedy.cc: New.
* testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc: Adjust
duplicate testcases.
* testsuite/performance/28_regex/split.h: New.
* testsuite/performance/28_regex/split_bfs.cc: New.
* testsuite/util/testsuite_regex.h: Adjust behavior of two-executors
agreement judger: do not compare match_results when executor return
false.
2013-10-25 François Dumont <fdumont@gcc.gnu.org>
* include/debug/formatter.h (__check_singular): Add const on
......
......@@ -36,6 +36,9 @@ namespace __detail
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
enum class _RegexExecutorPolicy : int
{ _S_auto, _S_alternate };
template<typename _BiIter, typename _Alloc,
typename _CharT, typename _TraitsT,
_RegexExecutorPolicy __policy,
......@@ -730,17 +733,6 @@ _GLIBCXX_END_NAMESPACE_VERSION
typedef std::shared_ptr<__detail::_NFA<_Ch_type, _Rx_traits>>
_AutomatonPtr;
template<typename _BiIter, typename _Alloc,
typename _CharT, typename _TraitsT,
__detail::_RegexExecutorPolicy __policy>
friend std::unique_ptr<
__detail::_Executor<_BiIter, _Alloc, _CharT, _TraitsT>>
__detail::__get_executor(_BiIter,
_BiIter,
std::vector<sub_match<_BiIter>, _Alloc>&,
const basic_regex<_CharT, _TraitsT>&,
regex_constants::match_flag_type);
template<typename _Bp, typename _Ap, typename _Cp, typename _Rp,
__detail::_RegexExecutorPolicy, bool>
friend bool
......@@ -748,15 +740,9 @@ _GLIBCXX_END_NAMESPACE_VERSION
const basic_regex<_Cp, _Rp>&,
regex_constants::match_flag_type);
template<typename, typename, typename, typename>
template<typename, typename, typename, bool>
friend class __detail::_Executor;
template<typename, typename, typename, typename>
friend class __detail::_DFSExecutor;
template<typename, typename, typename, typename>
friend class __detail::_BFSExecutor;
flag_type _M_flags;
_Rx_traits _M_traits;
_AutomatonPtr _M_automaton;
......@@ -1851,15 +1837,9 @@ _GLIBCXX_END_NAMESPACE_VERSION
//@}
private:
template<typename, typename, typename, typename>
template<typename, typename, typename, bool>
friend class __detail::_Executor;
template<typename, typename, typename, typename>
friend class __detail::_DFSExecutor;
template<typename, typename, typename, typename>
friend class __detail::_BFSExecutor;
template<typename, typename, typename>
friend class regex_iterator;
......
......@@ -28,6 +28,13 @@
* Do not attempt to use it directly. @headername{regex}
*/
// See below __regex_algo_impl to get what this is talking about. The default
// value 1 indicated a conservative optimization without giving up worst case
// performance.
#ifndef _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT
#define _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT 1
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
......@@ -61,14 +68,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
for (auto& __it : __res)
__it.matched = false;
auto __executor = __get_executor<_BiIter, _Alloc, _CharT, _TraitsT,
__policy>(__s, __e, __res, __re, __flags);
// This function decide which executor to use under given circumstances.
// The _S_auto policy now is the following: if a NFA has no
// back-references and has more than _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT
// quantifiers (*, +, ?), the BFS executor will be used, other wise
// DFS executor. This is because DFS executor has a exponential upper
// bound, but better best-case performace. Meanwhile, BFS executor can
// effectively prevent from exponential-long time matching (which must
// contains many quantifiers), but it's slower in average.
//
// For simple regex, BFS executor could be 2 or more times slower than
// DFS executor.
//
// Of course, BFS executor cannot handle back-references.
bool __ret;
if (__match_mode)
__ret = __executor->_M_match();
if (!__re._M_automaton->_M_has_backref
&& (__policy == _RegexExecutorPolicy::_S_alternate
|| __re._M_automaton->_M_quant_count
> _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT))
{
_Executor<_BiIter, _Alloc, _TraitsT, false>
__executor(__s, __e, __m, __re, __flags);
if (__match_mode)
__ret = __executor._M_match();
else
__ret = __executor._M_search();
}
else
__ret = __executor->_M_search();
{
_Executor<_BiIter, _Alloc, _TraitsT, true>
__executor(__s, __e, __m, __re, __flags);
if (__match_mode)
__ret = __executor._M_match();
else
__ret = __executor._M_search();
}
if (__ret)
{
for (auto __it : __res)
......
// { dg-options "-std=gnu++11" }
//
// 2013-07-29 Tim Shen <timshen91@gmail.com>
// 2013-10-24 Tim Shen <timshen91@gmail.com>
//
// Copyright (C) 2013 Free Software Foundation, Inc.
//
......@@ -21,47 +21,25 @@
// <http://www.gnu.org/licenses/>.
// 28.11.2 regex_match
// Tests Extended automatic matcher dispatching against a std::string target.
// Tests ECMAScript ungreedy match.
#include <regex>
#include <testsuite_hooks.h>
#include <testsuite_regex.h>
using namespace __gnu_test;
using namespace std;
template<typename _Bi_iter, typename _Alloc,
typename _Ch_type, typename _Rx_traits>
void
fake_match(_Bi_iter __s,
_Bi_iter __e,
match_results<_Bi_iter, _Alloc>& __m,
const basic_regex<_Ch_type, _Rx_traits>& __re,
regex_constants::match_flag_type __flags
= regex_constants::match_default)
{
using namespace __detail;
auto& __res = (vector<sub_match<_Bi_iter>, _Alloc>&)(__m);
VERIFY( (dynamic_cast
<_DFSExecutor<_Bi_iter, _Alloc, _Ch_type, _Rx_traits>*>
(&*__get_executor<_Bi_iter, _Alloc, _Ch_type, _Rx_traits,
_RegexExecutorPolicy::_S_auto>(__s, __e, __res, __re, __flags))
!= nullptr) );
}
void
test01()
{
bool test __attribute__((unused)) = true;
regex re("()(one(.*))abc\\1"); // backref cause DFS
const string target("onetwoabc");
smatch m;
fake_match(target.begin(), target.end(), m, re);
regex_match(target, m, re);
VERIFY( m[2].matched );
VERIFY( m[3].matched );
VERIFY( std::string(m[2].first, m[2].second) == "onetwo" );
VERIFY( std::string(m[3].first, m[3].second) == "two" );
regex re("(a*?)*?");
cmatch m;
VERIFY(regex_match("a", m, re));
VERIFY(m.size() == 2);
VERIFY(string(m[0].first, m[0].second) == "a");
}
int
......
......@@ -54,9 +54,9 @@ test01()
VERIFY(regex_search_debug("aaaa", m, regex("(a+)(a+)")));
TEST(1, "aaa");
TEST(2, "a");
VERIFY(regex_search_debug("aaaa", m, regex("(a+?)(a+)")));
TEST(1, "a");
TEST(2, "aaa");
VERIFY(regex_search_debug("aaaa", m, regex("(a+)(a+?)")));
TEST(1, "aaa");
TEST(2, "a");
VERIFY(regex_search_debug("aaaa", m, regex("(a+?)(a+)")));
TEST(1, "a");
TEST(2, "aaa");
......
......@@ -18,82 +18,12 @@
// 2013-10-08 Tim Shen <timshen91@gmail.com>
#include <testsuite_performance.h>
#include <regex>
#include "split.h"
using namespace __gnu_test;
using namespace std;
void split(string s)
{
regex re("\\s+");
for (auto it = sregex_token_iterator(s.begin(), s.end(), re, -1);
it != sregex_token_iterator();
++it)
{
}
}
int main()
{
string source = "\
// Copyright (C) 2013 Free Software Foundation, Inc.\n\
//\n\
// This file is part of the GNU ISO C++ Library. This library is free\n\
// software; you can redistribute it and/or modify it under the\n\
// terms of the GNU General Public License as published by the\n\
// Free Software Foundation; either version 3, or (at your option)\n\
// any later version.\n\
\n\
// This library is distributed in the hope that it will be useful,\n\
// but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
// GNU General Public License for more details.\n\
\n\
// You should have received a copy of the GNU General Public License along\n\
// with this library; see the file COPYING3. If not see\n\
// <http://www.gnu.org/licenses/>.\n\
\n\
// 2013-10-08 Tim Shen <timshen91@gmail.com>\n\
\n\
#include <testsuite_performance.h>\n\
#include <regex>\n\
\n\
using namespace __gnu_test;\n\
using namespace std;\n\
\n\
void split(string s)\n\
{\n\
regex re(\"\\s+\");\n\
for (auto it = sregex_token_iterator(s.begin(), s.end(), re, -1);\n\
it != sregex_token_iterator();\n\
++it)\n\
{\n\
}\n\
}\n\
\n\
int main()\n\
{\n\
string source = \"\";\n\
time_counter time;\n\
resource_counter resource;\n\
\n\
source = source + source;\n\
source = source + source;\n\
source = source + source;\n\
source = source + source;\n\
source = source + source;\n\
source = source + source;\n\
source = source + source;\n\
source = source + source;\n\
\n\
start_counters(time, resource);\n\
split(source);\n\
stop_counters(time, resource);\n\
report_performance(__FILE__, \"\", time, resource);\n\
\n\
return 0;\n\
}\n";
time_counter time;
resource_counter resource;
......
// Copyright (C) 2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// 2013-10-26 Tim Shen <timshen91@gmail.com>
#include <regex>
using namespace std;
void split(string s)
{
regex re("\\s+");
for (auto it = sregex_token_iterator(s.begin(), s.end(), re, -1);
it != sregex_token_iterator();
++it)
{
}
}
string source = "\
// Copyright (C) 2013 Free Software Foundation, Inc.\n\
//\n\
// This file is part of the GNU ISO C++ Library. This library is free\n\
// software; you can redistribute it and/or modify it under the\n\
// terms of the GNU General Public License as published by the\n\
// Free Software Foundation; either version 3, or (at your option)\n\
// any later version.\n\
\n\
// This library is distributed in the hope that it will be useful,\n\
// but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
// GNU General Public License for more details.\n\
\n\
// You should have received a copy of the GNU General Public License along\n\
// with this library; see the file COPYING3. If not see\n\
// <http://www.gnu.org/licenses/>.\n\
\n\
// 2013-10-08 Tim Shen <timshen91@gmail.com>\n\
\n\
#include <testsuite_performance.h>\n\
#include <regex>\n\
\n\
using namespace __gnu_test;\n\
using namespace std;\n\
\n\
void split(string s)\n\
{\n\
regex re(\"\\s+\");\n\
for (auto it = sregex_token_iterator(s.begin(), s.end(), re, -1);\n\
it != sregex_token_iterator();\n\
++it)\n\
{\n\
}\n\
}\n\
\n\
int main()\n\
{\n\
string source = \"\";\n\
time_counter time;\n\
resource_counter resource;\n\
\n\
source = source + source;\n\
source = source + source;\n\
source = source + source;\n\
source = source + source;\n\
source = source + source;\n\
source = source + source;\n\
source = source + source;\n\
source = source + source;\n\
\n\
start_counters(time, resource);\n\
split(source);\n\
stop_counters(time, resource);\n\
report_performance(__FILE__, \"\", time, resource);\n\
\n\
return 0;\n\
}\n";
// Copyright (C) 2013 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// 2013-10-26 Tim Shen <timshen91@gmail.com>
#include <testsuite_performance.h>
#define _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT 0
#include "split.h"
using namespace __gnu_test;
int main()
{
time_counter time;
resource_counter resource;
source = source + source;
source = source + source;
source = source + source;
source = source + source;
source = source + source;
source = source + source;
source = source + source;
source = source + source;
start_counters(time, resource);
split(source);
stop_counters(time, resource);
report_performance(__FILE__, "", time, resource);
return 0;
}
......@@ -150,7 +150,8 @@ namespace __gnu_test
auto __res2 = __regex_algo_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits,
_RegexExecutorPolicy::_S_alternate, true>
(__s, __e, __mm, __re, __flags);
if (__res1 == __res2 && __m == __mm)
// __m is unspecified if return value is false.
if (__res1 == __res2 && (!__res1 || __m == __mm))
return __res1;
throw(std::exception());
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment