re PR libstdc++/58358 (search_n has a Complexity violation for random access iterator)
2013-09-11 Mitsuru Kariya <kariya_mitsuru@hotmail.com> Chris Jefferson <chris@bubblescope.net> PR libstdc++/58358 * include/bits/stl_algo.h (search_n): Fix to guarantee a number of comparisons <= number of elements in the range. * testsuite/25_algorithms/search_n/58358.cc: New. * testsuite/25_algorithms/search_n/iterator.cc: Extend. Co-Authored-By: Chris Jefferson <chris@bubblescope.net> From-SVN: r202510
This commit is contained in:
parent
088845a5f0
commit
4b47d65500
4 changed files with 80 additions and 52 deletions
|
@ -1,3 +1,12 @@
|
|||
2013-09-11 Mitsuru Kariya <kariya_mitsuru@hotmail.com>
|
||||
Chris Jefferson <chris@bubblescope.net>
|
||||
|
||||
PR libstdc++/58358
|
||||
* include/bits/stl_algo.h (search_n): Fix to guarantee a number
|
||||
of comparisons <= number of elements in the range.
|
||||
* testsuite/25_algorithms/search_n/58358.cc: New.
|
||||
* testsuite/25_algorithms/search_n/iterator.cc: Extend.
|
||||
|
||||
2013-09-10 Ed Smith-Rowland <3dw4rd@verizon.net>
|
||||
|
||||
* testsuite/28_regex/traits/wchar_t/value.cc: Change template args
|
||||
|
|
|
@ -385,38 +385,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
_DistanceType;
|
||||
|
||||
_DistanceType __tailSize = __last - __first;
|
||||
const _DistanceType __pattSize = __count;
|
||||
_DistanceType __remainder = __count;
|
||||
|
||||
if (__tailSize < __pattSize)
|
||||
return __last;
|
||||
|
||||
const _DistanceType __skipOffset = __pattSize - 1;
|
||||
_RandomAccessIter __lookAhead = __first + __skipOffset;
|
||||
__tailSize -= __pattSize;
|
||||
|
||||
while (1) // the main loop...
|
||||
while (__remainder <= __tailSize) // the main loop...
|
||||
{
|
||||
// __lookAhead here is always pointing to the last element of next
|
||||
// possible match.
|
||||
while (!(*__lookAhead == __val)) // the skip loop...
|
||||
{
|
||||
if (__tailSize < __pattSize)
|
||||
return __last; // Failure
|
||||
__lookAhead += __pattSize;
|
||||
__tailSize -= __pattSize;
|
||||
}
|
||||
_DistanceType __remainder = __skipOffset;
|
||||
for (_RandomAccessIter __backTrack = __lookAhead - 1;
|
||||
*__backTrack == __val; --__backTrack)
|
||||
__first += __remainder;
|
||||
__tailSize -= __remainder;
|
||||
// __first here is always pointing to one past the last element of
|
||||
// next possible match.
|
||||
_RandomAccessIter __backTrack = __first;
|
||||
while (*--__backTrack == __val)
|
||||
{
|
||||
if (--__remainder == 0)
|
||||
return (__lookAhead - __skipOffset); // Success
|
||||
return (__first - __count); // Success
|
||||
}
|
||||
if (__remainder > __tailSize)
|
||||
return __last; // Failure
|
||||
__lookAhead += __remainder;
|
||||
__tailSize -= __remainder;
|
||||
__remainder = __count + 1 - (__first - __backTrack);
|
||||
}
|
||||
return __last; // Failure
|
||||
}
|
||||
|
||||
// search_n
|
||||
|
@ -478,38 +463,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
_DistanceType;
|
||||
|
||||
_DistanceType __tailSize = __last - __first;
|
||||
const _DistanceType __pattSize = __count;
|
||||
_DistanceType __remainder = __count;
|
||||
|
||||
if (__tailSize < __pattSize)
|
||||
return __last;
|
||||
|
||||
const _DistanceType __skipOffset = __pattSize - 1;
|
||||
_RandomAccessIter __lookAhead = __first + __skipOffset;
|
||||
__tailSize -= __pattSize;
|
||||
|
||||
while (1) // the main loop...
|
||||
while (__remainder <= __tailSize) // the main loop...
|
||||
{
|
||||
// __lookAhead here is always pointing to the last element of next
|
||||
// possible match.
|
||||
while (!bool(__binary_pred(*__lookAhead, __val))) // the skip loop...
|
||||
{
|
||||
if (__tailSize < __pattSize)
|
||||
return __last; // Failure
|
||||
__lookAhead += __pattSize;
|
||||
__tailSize -= __pattSize;
|
||||
}
|
||||
_DistanceType __remainder = __skipOffset;
|
||||
for (_RandomAccessIter __backTrack = __lookAhead - 1;
|
||||
__binary_pred(*__backTrack, __val); --__backTrack)
|
||||
__first += __remainder;
|
||||
__tailSize -= __remainder;
|
||||
// __first here is always pointing to one past the last element of
|
||||
// next possible match.
|
||||
_RandomAccessIter __backTrack = __first;
|
||||
while (__binary_pred(*--__backTrack, __val))
|
||||
{
|
||||
if (--__remainder == 0)
|
||||
return (__lookAhead - __skipOffset); // Success
|
||||
return (__first - __count); // Success
|
||||
}
|
||||
if (__remainder > __tailSize)
|
||||
return __last; // Failure
|
||||
__lookAhead += __remainder;
|
||||
__tailSize -= __remainder;
|
||||
__remainder = __count + 1 - (__first - __backTrack);
|
||||
}
|
||||
return __last; // Failure
|
||||
}
|
||||
|
||||
// find_end for forward iterators.
|
||||
|
|
41
libstdc++-v3/testsuite/25_algorithms/search_n/58358.cc
Normal file
41
libstdc++-v3/testsuite/25_algorithms/search_n/58358.cc
Normal file
|
@ -0,0 +1,41 @@
|
|||
// 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/>.
|
||||
|
||||
// { dg-options "-std=gnu++11" }
|
||||
|
||||
// 25.1.9 [lib.alg.search]
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void test01()
|
||||
{
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
std::vector<int> a{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
int count = 0;
|
||||
std::search_n(a.begin(), a.end(), 10, 1,
|
||||
[&count](int t, int u) { ++count; return t == u; });
|
||||
VERIFY( count <= 11 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
|
@ -31,9 +31,11 @@
|
|||
int array1[11] = {0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0};
|
||||
int array2[TEST_DEPTH];
|
||||
|
||||
int pred_count;
|
||||
bool
|
||||
pred(int i, int j)
|
||||
{
|
||||
++pred_count;
|
||||
return i == j;
|
||||
}
|
||||
|
||||
|
@ -90,16 +92,22 @@ int main()
|
|||
|
||||
int* t1 = search_n(forwardcon.begin(),
|
||||
forwardcon.end(), j, 1).ptr;
|
||||
pred_count = 0;
|
||||
int* t2 = search_n(forwardcon.begin(),
|
||||
forwardcon.end(), j, 1, pred).ptr;
|
||||
VERIFY(pred_count <= i);
|
||||
int* t3 = search_n(bidircon.begin(),
|
||||
bidircon.end(), j, 1).ptr;
|
||||
pred_count = 0;
|
||||
int* t4 = search_n(bidircon.begin(),
|
||||
bidircon.end(), j, 1, pred).ptr;
|
||||
VERIFY(pred_count <= i);
|
||||
int* t5 = search_n(randomcon.begin(),
|
||||
randomcon.end(), j, 1).ptr;
|
||||
pred_count = 0;
|
||||
int* t6 = search_n(randomcon.begin(),
|
||||
randomcon.end(), j, 1, pred).ptr;
|
||||
VERIFY(pred_count <= i);
|
||||
VERIFY((t1 == t2) && (t2 == t3) && (t3 == t4) &&
|
||||
(t4 == t5) && (t5 == t6));
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue