mirror of git://gcc.gnu.org/git/gcc.git
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
|
|
@ -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>
|
2013-09-10 Ed Smith-Rowland <3dw4rd@verizon.net>
|
||||||
|
|
||||||
* testsuite/28_regex/traits/wchar_t/value.cc: Change template args
|
* testsuite/28_regex/traits/wchar_t/value.cc: Change template args
|
||||||
|
|
|
||||||
|
|
@ -385,38 +385,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
_DistanceType;
|
_DistanceType;
|
||||||
|
|
||||||
_DistanceType __tailSize = __last - __first;
|
_DistanceType __tailSize = __last - __first;
|
||||||
const _DistanceType __pattSize = __count;
|
_DistanceType __remainder = __count;
|
||||||
|
|
||||||
if (__tailSize < __pattSize)
|
while (__remainder <= __tailSize) // the main loop...
|
||||||
return __last;
|
|
||||||
|
|
||||||
const _DistanceType __skipOffset = __pattSize - 1;
|
|
||||||
_RandomAccessIter __lookAhead = __first + __skipOffset;
|
|
||||||
__tailSize -= __pattSize;
|
|
||||||
|
|
||||||
while (1) // the main loop...
|
|
||||||
{
|
{
|
||||||
// __lookAhead here is always pointing to the last element of next
|
__first += __remainder;
|
||||||
// possible match.
|
__tailSize -= __remainder;
|
||||||
while (!(*__lookAhead == __val)) // the skip loop...
|
// __first here is always pointing to one past the last element of
|
||||||
{
|
// next possible match.
|
||||||
if (__tailSize < __pattSize)
|
_RandomAccessIter __backTrack = __first;
|
||||||
return __last; // Failure
|
while (*--__backTrack == __val)
|
||||||
__lookAhead += __pattSize;
|
|
||||||
__tailSize -= __pattSize;
|
|
||||||
}
|
|
||||||
_DistanceType __remainder = __skipOffset;
|
|
||||||
for (_RandomAccessIter __backTrack = __lookAhead - 1;
|
|
||||||
*__backTrack == __val; --__backTrack)
|
|
||||||
{
|
{
|
||||||
if (--__remainder == 0)
|
if (--__remainder == 0)
|
||||||
return (__lookAhead - __skipOffset); // Success
|
return (__first - __count); // Success
|
||||||
}
|
}
|
||||||
if (__remainder > __tailSize)
|
__remainder = __count + 1 - (__first - __backTrack);
|
||||||
return __last; // Failure
|
|
||||||
__lookAhead += __remainder;
|
|
||||||
__tailSize -= __remainder;
|
|
||||||
}
|
}
|
||||||
|
return __last; // Failure
|
||||||
}
|
}
|
||||||
|
|
||||||
// search_n
|
// search_n
|
||||||
|
|
@ -478,38 +463,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
_DistanceType;
|
_DistanceType;
|
||||||
|
|
||||||
_DistanceType __tailSize = __last - __first;
|
_DistanceType __tailSize = __last - __first;
|
||||||
const _DistanceType __pattSize = __count;
|
_DistanceType __remainder = __count;
|
||||||
|
|
||||||
if (__tailSize < __pattSize)
|
while (__remainder <= __tailSize) // the main loop...
|
||||||
return __last;
|
|
||||||
|
|
||||||
const _DistanceType __skipOffset = __pattSize - 1;
|
|
||||||
_RandomAccessIter __lookAhead = __first + __skipOffset;
|
|
||||||
__tailSize -= __pattSize;
|
|
||||||
|
|
||||||
while (1) // the main loop...
|
|
||||||
{
|
{
|
||||||
// __lookAhead here is always pointing to the last element of next
|
__first += __remainder;
|
||||||
// possible match.
|
__tailSize -= __remainder;
|
||||||
while (!bool(__binary_pred(*__lookAhead, __val))) // the skip loop...
|
// __first here is always pointing to one past the last element of
|
||||||
{
|
// next possible match.
|
||||||
if (__tailSize < __pattSize)
|
_RandomAccessIter __backTrack = __first;
|
||||||
return __last; // Failure
|
while (__binary_pred(*--__backTrack, __val))
|
||||||
__lookAhead += __pattSize;
|
|
||||||
__tailSize -= __pattSize;
|
|
||||||
}
|
|
||||||
_DistanceType __remainder = __skipOffset;
|
|
||||||
for (_RandomAccessIter __backTrack = __lookAhead - 1;
|
|
||||||
__binary_pred(*__backTrack, __val); --__backTrack)
|
|
||||||
{
|
{
|
||||||
if (--__remainder == 0)
|
if (--__remainder == 0)
|
||||||
return (__lookAhead - __skipOffset); // Success
|
return (__first - __count); // Success
|
||||||
}
|
}
|
||||||
if (__remainder > __tailSize)
|
__remainder = __count + 1 - (__first - __backTrack);
|
||||||
return __last; // Failure
|
|
||||||
__lookAhead += __remainder;
|
|
||||||
__tailSize -= __remainder;
|
|
||||||
}
|
}
|
||||||
|
return __last; // Failure
|
||||||
}
|
}
|
||||||
|
|
||||||
// find_end for forward iterators.
|
// find_end for forward iterators.
|
||||||
|
|
|
||||||
|
|
@ -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 array1[11] = {0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0};
|
||||||
int array2[TEST_DEPTH];
|
int array2[TEST_DEPTH];
|
||||||
|
|
||||||
|
int pred_count;
|
||||||
bool
|
bool
|
||||||
pred(int i, int j)
|
pred(int i, int j)
|
||||||
{
|
{
|
||||||
|
++pred_count;
|
||||||
return i == j;
|
return i == j;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,16 +92,22 @@ int main()
|
||||||
|
|
||||||
int* t1 = search_n(forwardcon.begin(),
|
int* t1 = search_n(forwardcon.begin(),
|
||||||
forwardcon.end(), j, 1).ptr;
|
forwardcon.end(), j, 1).ptr;
|
||||||
|
pred_count = 0;
|
||||||
int* t2 = search_n(forwardcon.begin(),
|
int* t2 = search_n(forwardcon.begin(),
|
||||||
forwardcon.end(), j, 1, pred).ptr;
|
forwardcon.end(), j, 1, pred).ptr;
|
||||||
|
VERIFY(pred_count <= i);
|
||||||
int* t3 = search_n(bidircon.begin(),
|
int* t3 = search_n(bidircon.begin(),
|
||||||
bidircon.end(), j, 1).ptr;
|
bidircon.end(), j, 1).ptr;
|
||||||
|
pred_count = 0;
|
||||||
int* t4 = search_n(bidircon.begin(),
|
int* t4 = search_n(bidircon.begin(),
|
||||||
bidircon.end(), j, 1, pred).ptr;
|
bidircon.end(), j, 1, pred).ptr;
|
||||||
|
VERIFY(pred_count <= i);
|
||||||
int* t5 = search_n(randomcon.begin(),
|
int* t5 = search_n(randomcon.begin(),
|
||||||
randomcon.end(), j, 1).ptr;
|
randomcon.end(), j, 1).ptr;
|
||||||
|
pred_count = 0;
|
||||||
int* t6 = search_n(randomcon.begin(),
|
int* t6 = search_n(randomcon.begin(),
|
||||||
randomcon.end(), j, 1, pred).ptr;
|
randomcon.end(), j, 1, pred).ptr;
|
||||||
|
VERIFY(pred_count <= i);
|
||||||
VERIFY((t1 == t2) && (t2 == t3) && (t3 == t4) &&
|
VERIFY((t1 == t2) && (t2 == t3) && (t3 == t4) &&
|
||||||
(t4 == t5) && (t5 == t6));
|
(t4 == t5) && (t5 == t6));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue