[libstdc++/71500] make back reference work with icase
Jonathan Wakely
jwakely@redhat.com
Mon Sep 18 17:26:00 GMT 2017
On 15/09/17 16:39 +0100, Jonathan Wakely wrote:
>On 04/09/17 03:31 -0700, Tim Shen via libstdc++ wrote:
>>This fixes the follow-up comments in 71500.
>>
>>Back-reference matching is different from other matching, as the
>>content the back-reference refers to is at "run-time", aka during
>>regex_match(), not regex() compilation.
>>
>>For compilation we do have an abstraction layer to catch all
>>comparison customizations, namely _M_translator in regex_compiler.h.
>>Until this patch, we don't have an abstraction for "run-time"
>>matching. I believe that back-reference is the only place that needs
>>run-time matching, so I just build a _Backref_matcher in
>>regex_executot.tcc.
>>
>>Tested on x86_64-linux-gnu.
>>
>>Thanks!
>>
>>--
>>Regards,
>>Tim Shen
>
>>commit a97b7fecd319e031ffc489a956b8cf3dc63eeb26
>>Author: Tim Shen <timshen@google.com>
>>Date: Mon Sep 4 03:19:35 2017 -0700
>>
>> PR libstdc++/71500
>> * include/bits/regex_executor.tcc: Support icase in
>> regex_tratis<...> for back reference matches.
>> * testsuite/28_regex/regression.cc: Test case.
>>
>>diff --git a/libstdc++-v3/include/bits/regex_executor.tcc b/libstdc++-v3/include/bits/regex_executor.tcc
>>index 226e05856e1..f6149fecf9d 100644
>>--- a/libstdc++-v3/include/bits/regex_executor.tcc
>>+++ b/libstdc++-v3/include/bits/regex_executor.tcc
>>@@ -335,6 +335,54 @@ namespace __detail
>> _M_states._M_queue(__state._M_next, _M_cur_results);
>> }
>>
>>+ template<typename _BiIter, typename _TraitsT>
>>+ struct _Backref_matcher
>>+ {
>>+ _Backref_matcher(bool __icase, const _TraitsT& __traits)
>>+ : _M_traits(__traits) { }
>>+
>>+ bool
>>+ _M_apply(_BiIter __expected_begin,
>>+ _BiIter __expected_end, _BiIter __actual_begin,
>>+ _BiIter __actual_end)
>>+ {
>>+ return _M_traits.transform(__expected_begin, __expected_end)
>>+ == _M_traits.transform(__actual_begin, __actual_end);
>>+ }
>>+
>>+ const _TraitsT& _M_traits;
>>+ };
>>+
>>+ template<typename _BiIter, typename _CharT>
>>+ struct _Backref_matcher<_BiIter, std::regex_traits<_CharT>>
>>+ {
>>+ using _TraitsT = std::regex_traits<_CharT>;
>>+ _Backref_matcher(bool __icase, const _TraitsT& __traits)
>>+ : _M_icase(__icase), _M_traits(__traits) { }
>>+
>>+ bool
>>+ _M_apply(_BiIter __expected_begin,
>>+ _BiIter __expected_end, _BiIter __actual_begin,
>>+ _BiIter __actual_end)
>>+ {
>>+ if (!_M_icase)
>>+ return std::equal(__expected_begin, __expected_end,
>>+ __actual_begin, __actual_end);
>
>This is only valid in C++14 and higher, because the 4-argument version
>of std::equal isn't present in C++11.
>
>>+ typedef std::ctype<_CharT> __ctype_type;
>>+ const auto& __fctyp = use_facet<__ctype_type>(_M_traits.getloc());
>>+ return std::equal(__expected_begin, __expected_end,
>>+ __actual_begin, __actual_end,
>
>Same here.
>
>>+ [this, &__fctyp](_CharT __lhs, _CharT __rhs)
>>+ {
>>+ return __fctyp.tolower(__lhs)
>>+ == __fctyp.tolower(__rhs);
>>+ });
>
>We need to rewrite this to check the lengths are equal first, and then
>call the 3-argument version of std::equal.
>
>Alternatively, we could move the implementation of the C++14
>std::equal overloads to __equal and make that available for C++11.
>I'll try that.
Here's a proof of concept patch for that. It's a bit ugly.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch.txt
Type: text/x-patch
Size: 5923 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20170918/d86710a5/attachment.bin>
More information about the Libstdc++
mailing list