2012-05-29 François Dumont <fdumont@gcc.gnu.org>

* include/bits/stl_tempbuf.h (__uninitialized_construct_buf)
	(__uninitialized_construct_buf_dispatch<>::__ucr): Fix to work
	with iterator returning rvalue.
	* testsuite/25_algorithms/stable_sort/3.cc: New.

From-SVN: r187985
This commit is contained in:
François Dumont 2012-05-29 19:29:29 +00:00
parent 678abdd924
commit 80a009e565
3 changed files with 68 additions and 20 deletions

View File

@ -1,3 +1,10 @@
2012-05-29 François Dumont <fdumont@gcc.gnu.org>
* include/bits/stl_tempbuf.h (__uninitialized_construct_buf)
(__uninitialized_construct_buf_dispatch<>::__ucr): Fix to work
with iterator returning rvalue.
* testsuite/25_algorithms/stable_sort/3.cc: New.
2012-05-28 Paolo Carlini <paolo.carlini@oracle.com> 2012-05-28 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/53503 PR c++/53503

View File

@ -1,7 +1,7 @@
// Temporary buffer implementation -*- C++ -*- // Temporary buffer implementation -*- C++ -*-
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
// 2010, 2011 // 2010, 2011, 2012
// Free Software Foundation, Inc. // Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // This file is part of the GNU ISO C++ Library. This library is free
@ -182,25 +182,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<bool> template<bool>
struct __uninitialized_construct_buf_dispatch struct __uninitialized_construct_buf_dispatch
{ {
template<typename _ForwardIterator, typename _Tp> template<typename _Pointer, typename _ForwardIterator>
static void static void
__ucr(_ForwardIterator __first, _ForwardIterator __last, __ucr(_Pointer __first, _Pointer __last,
_Tp& __value) _ForwardIterator __seed)
{ {
if(__first == __last) if(__first == __last)
return; return;
_ForwardIterator __cur = __first; _Pointer __cur = __first;
__try __try
{ {
std::_Construct(std::__addressof(*__first), std::_Construct(std::__addressof(*__first),
_GLIBCXX_MOVE(__value)); _GLIBCXX_MOVE(*__seed));
_ForwardIterator __prev = __cur; _Pointer __prev = __cur;
++__cur; ++__cur;
for(; __cur != __last; ++__cur, ++__prev) for(; __cur != __last; ++__cur, ++__prev)
std::_Construct(std::__addressof(*__cur), std::_Construct(std::__addressof(*__cur),
_GLIBCXX_MOVE(*__prev)); _GLIBCXX_MOVE(*__prev));
__value = _GLIBCXX_MOVE(*__prev); *__seed = _GLIBCXX_MOVE(*__prev);
} }
__catch(...) __catch(...)
{ {
@ -213,9 +213,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<> template<>
struct __uninitialized_construct_buf_dispatch<true> struct __uninitialized_construct_buf_dispatch<true>
{ {
template<typename _ForwardIterator, typename _Tp> template<typename _Pointer, typename _ForwardIterator>
static void static void
__ucr(_ForwardIterator, _ForwardIterator, _Tp&) { } __ucr(_Pointer, _Pointer, _ForwardIterator) { }
}; };
// Constructs objects in the range [first, last). // Constructs objects in the range [first, last).
@ -223,23 +223,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// their exact value is not defined. In particular they may // their exact value is not defined. In particular they may
// be 'moved from'. // be 'moved from'.
// //
// While __value may altered during this algorithm, it will have // While *__seed may be altered during this algorithm, it will have
// the same value when the algorithm finishes, unless one of the // the same value when the algorithm finishes, unless one of the
// constructions throws. // constructions throws.
// //
// Requirements: _ForwardIterator::value_type(_Tp&&) is valid. // Requirements: _Pointer::value_type(_Tp&&) is valid.
template<typename _ForwardIterator, typename _Tp> template<typename _Pointer, typename _ForwardIterator>
inline void inline void
__uninitialized_construct_buf(_ForwardIterator __first, __uninitialized_construct_buf(_Pointer __first, _Pointer __last,
_ForwardIterator __last, _ForwardIterator __seed)
_Tp& __value)
{ {
typedef typename std::iterator_traits<_ForwardIterator>::value_type typedef typename std::iterator_traits<_Pointer>::value_type
_ValueType; _ValueType;
std::__uninitialized_construct_buf_dispatch< std::__uninitialized_construct_buf_dispatch<
__has_trivial_constructor(_ValueType)>:: __has_trivial_constructor(_ValueType)>::
__ucr(__first, __last, __value); __ucr(__first, __last, __seed);
} }
template<typename _ForwardIterator, typename _Tp> template<typename _ForwardIterator, typename _Tp>
@ -256,7 +255,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_len = __p.second; _M_len = __p.second;
if (_M_buffer) if (_M_buffer)
std::__uninitialized_construct_buf(_M_buffer, _M_buffer + _M_len, std::__uninitialized_construct_buf(_M_buffer, _M_buffer + _M_len,
*__first); __first);
} }
__catch(...) __catch(...)
{ {

View File

@ -0,0 +1,42 @@
// Copyright (C) 2012 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/>.
// 25.3.1.2 [lib.stable.sort]
#include <vector>
#include <algorithm>
#include <testsuite_hooks.h>
void
test1()
{
bool test __attribute__((unused)) = true;
std::vector<bool> bools;
bools.push_back(true);
bools.push_back(false);
bools.push_back(true);
bools.push_back(false);
std::stable_sort(bools.begin(), bools.end());
VERIFY( !bools[0] && !bools[1] && bools[2] && bools[3] );
}
int
main()
{
test1();
}