This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
RE: [PATCH] improve string find algorithm
- From: Aditya Kumar <aditya dot k7 at samsung dot com>
- To: 'Jonathan Wakely' <jwakely at redhat dot com>
- Cc: libstdc++ at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org, hiraditya at msn dot com
- Date: Fri, 06 Jan 2017 14:34:02 -0600
- Subject: RE: [PATCH] improve string find algorithm
- Authentication-results: sourceware.org; auth=none
- Cms-type: 301P
- References: <1481132816-31162-1-git-send-email-aditya.k7@samsung.com> <CGME20170106133507epcas2p15eaabe5ca279349c9f3603a6c2bb61d8@epcas2p1.samsung.com> <20170106133502.GB2966@redhat.com> <016101d2682b$136dc890$3a4959b0$@samsung.com> <20170106202058.GH2966@redhat.com>
Thanks for the correction and updating the comments.
-Aditya
-----Original Message-----
From: Jonathan Wakely [mailto:jwakely@redhat.com]
Sent: Friday, January 06, 2017 2:21 PM
To: Aditya Kumar
Cc: libstdc++@gcc.gnu.org; gcc-patches@gcc.gnu.org; hiraditya@msn.com
Subject: Re: [PATCH] improve string find algorithm
On 06/01/17 08:42 -0600, Aditya Kumar wrote:
>Yes, we do.
>Sorry for the mistake, it happened because I first wrote this for
>libcxx (https://reviews.llvm.org/D27068) and while porting that line
>got missed.
>
>Thanks,
>-Aditya
>
>
>diff --git a/libstdc++-v3/include/bits/basic_string.tcc
>b/libstdc++-v3/include/bits/basic_string.tcc
>index df1e8dd..7942ee6 100644
>--- a/libstdc++-v3/include/bits/basic_string.tcc
>+++ b/libstdc++-v3/include/bits/basic_string.tcc
>@@ -1194,14 +1194,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> if (__n == 0)
> return __pos <= __size ? __pos : npos;
>
>- if (__n <= __size)
>- {
>- for (; __pos <= __size - __n; ++__pos)
>- if (traits_type::eq(__data[__pos], __s[0])
>- && traits_type::compare(__data + __pos + 1,
>- __s + 1, __n - 1) == 0)
>- return __pos;
>- }
>+ if (__n > __size)
>+ return npos;
>+
>+ const _CharT __elem0 = __s[0];
>+ const _CharT* __first1 = __data;
>+ const _CharT* __first2 = __s;
>+ const _CharT* __last1 = __data + __size;
>+ ptrdiff_t __len2 = __n - __pos;
What's this variable for?
>+ while (true) {
>+ ptrdiff_t __len1 = __last1 - __first1;
>+ if (__len1 < __len2)
>+ return npos;
>+
>+ // Find the first match.
>+ __first1 = traits_type::find(__first1, __len1 - __len2 + 1,
__elem0);
>+ if (__first1 == 0)
>+ return npos;
>+ // Compare the full string when first match is found.
>+ if (traits_type::compare(__first1, __first2, __len2) == 0)
>+ return __first1 - __data;
>+
>+ ++__first1;
>+ }
>+
> return npos;
> }
This is still wrong, consider std::string("abcd").find("ab", 2)
This should return npos, but you return 0. The postcondition for the
function is that the return value is not less than the pos argument.
The attached patch should be a correct version of the improved
algorithm.