From f4c5578ffbdaf421e70882c6cafc63f32faa30d1 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Thu, 31 May 2007 11:13:57 +0000 Subject: [PATCH] PR c++/32158 (libstdc++ bits) 2007-05-31 Paolo Carlini PR c++/32158 (libstdc++ bits) * include/bits/stl_uninitialized.h (__uninitialized_copy_aux, __uninitialized_fill_aux, __uninitialized_fill_n_aux): Remove. (struct __uninitialized_copy, struct __uninitialized_fill, struct __uninitialized_fill_n): Add. (uninitialized_copy, uninitialized_fill, uninitialized_fill_n): Adjust. * testsuite/20_util/specialized_algorithms/32158.cc: New. * include/bits/stl_uninitialized.h (uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator)): Robustify vs non-POD input. * include/bits/stl_vector.h (_M_fill_initialize): New. (vector(size_type, const value_type&, const allocator_type&), _M_initialize_dispatch(_Integer, _Integer, __true_type)): Use it. * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc: Adjust dg-error line. * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc: Likewise. * testsuite/23_containers/vector/requirements/dr438/ constructor_1_neg.cc: Likewise. * testsuite/23_containers/vector/requirements/dr438/ constructor_2_neg.cc: Likewise. From-SVN: r125223 --- libstdc++-v3/ChangeLog | 27 +++ libstdc++-v3/include/bits/stl_uninitialized.h | 162 +++++++++++------- libstdc++-v3/include/bits/stl_vector.h | 21 +-- .../20_util/specialized_algorithms/32158.cc | 35 ++++ .../vector/requirements/dr438/assign_neg.cc | 2 +- .../requirements/dr438/constructor_1_neg.cc | 2 +- .../requirements/dr438/constructor_2_neg.cc | 2 +- .../vector/requirements/dr438/insert_neg.cc | 2 +- 8 files changed, 178 insertions(+), 75 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/specialized_algorithms/32158.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c4bdb2cce59..4259ef3e30b 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,30 @@ +2007-05-31 Paolo Carlini + + PR c++/32158 (libstdc++ bits) + * include/bits/stl_uninitialized.h (__uninitialized_copy_aux, + __uninitialized_fill_aux, __uninitialized_fill_n_aux): + Remove. + (struct __uninitialized_copy, struct __uninitialized_fill, + struct __uninitialized_fill_n): Add. + (uninitialized_copy, uninitialized_fill, uninitialized_fill_n): + Adjust. + * testsuite/20_util/specialized_algorithms/32158.cc: New. + + * include/bits/stl_uninitialized.h (uninitialized_copy(_InputIterator, + _InputIterator, _ForwardIterator)): Robustify vs non-POD input. + + * include/bits/stl_vector.h (_M_fill_initialize): New. + (vector(size_type, const value_type&, const allocator_type&), + _M_initialize_dispatch(_Integer, _Integer, __true_type)): Use it. + * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc: + Adjust dg-error line. + * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc: + Likewise. + * testsuite/23_containers/vector/requirements/dr438/ + constructor_1_neg.cc: Likewise. + * testsuite/23_containers/vector/requirements/dr438/ + constructor_2_neg.cc: Likewise. + 2007-05-29 Paolo Carlini * aclocal.m4: Regenerate. diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h index 8b5548e213f..c564c21e3fd 100644 --- a/libstdc++-v3/include/bits/stl_uninitialized.h +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -64,25 +64,38 @@ _GLIBCXX_BEGIN_NAMESPACE(std) - template - _ForwardIterator - __uninitialized_copy_aux(_InputIterator __first, - _InputIterator __last, - _ForwardIterator __result) + template + struct __uninitialized_copy { - _ForwardIterator __cur = __result; - try - { - for (; __first != __last; ++__first, ++__cur) - std::_Construct(&*__cur, *__first); - return __cur; + template + static _ForwardIterator + uninitialized_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result) + { + _ForwardIterator __cur = __result; + try + { + for (; __first != __last; ++__first, ++__cur) + std::_Construct(&*__cur, *__first); + return __cur; + } + catch(...) + { + std::_Destroy(__result, __cur); + __throw_exception_again; + } } - catch(...) - { - std::_Destroy(__result, __cur); - __throw_exception_again; - } - } + }; + + template<> + struct __uninitialized_copy + { + template + static _ForwardIterator + uninitialized_copy(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result) + { return std::copy(__first, __last, __result); } + }; /** * @brief Copies the range [first,last) into result. @@ -98,33 +111,48 @@ _GLIBCXX_BEGIN_NAMESPACE(std) uninitialized_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result) { + typedef typename iterator_traits<_InputIterator>::value_type + _ValueType1; typedef typename iterator_traits<_ForwardIterator>::value_type - _ValueType; - if (__is_pod(_ValueType)) - return std::copy(__first, __last, __result); - else - return std::__uninitialized_copy_aux(__first, __last, __result); + _ValueType2; + + return std::__uninitialized_copy<(__is_pod(_ValueType1) + && __is_pod(_ValueType2))>:: + uninitialized_copy(__first, __last, __result); } - template - void - __uninitialized_fill_aux(_ForwardIterator __first, - _ForwardIterator __last, - const _Tp& __x) + template + struct __uninitialized_fill { - _ForwardIterator __cur = __first; - try - { - for (; __cur != __last; ++__cur) - std::_Construct(&*__cur, __x); + template + static void + uninitialized_fill(_ForwardIterator __first, + _ForwardIterator __last, const _Tp& __x) + { + _ForwardIterator __cur = __first; + try + { + for (; __cur != __last; ++__cur) + std::_Construct(&*__cur, __x); + } + catch(...) + { + std::_Destroy(__first, __cur); + __throw_exception_again; + } } - catch(...) - { - std::_Destroy(__first, __cur); - __throw_exception_again; - } - } + }; + + template<> + struct __uninitialized_fill + { + template + static void + uninitialized_fill(_ForwardIterator __first, + _ForwardIterator __last, const _Tp& __x) + { std::fill(__first, __last, __x); } + }; /** * @brief Copies the value x into the range [first,last). @@ -142,30 +170,43 @@ _GLIBCXX_BEGIN_NAMESPACE(std) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - if (__is_pod(_ValueType)) - std::fill(__first, __last, __x); - else - std::__uninitialized_fill_aux(__first, __last, __x); + + std::__uninitialized_fill<__is_pod(_ValueType)>:: + uninitialized_fill(__first, __last, __x); } - template - void - __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, - const _Tp& __x) + template + struct __uninitialized_fill_n { - _ForwardIterator __cur = __first; - try - { - for (; __n > 0; --__n, ++__cur) - std::_Construct(&*__cur, __x); + template + static void + uninitialized_fill_n(_ForwardIterator __first, _Size __n, + const _Tp& __x) + { + _ForwardIterator __cur = __first; + try + { + for (; __n > 0; --__n, ++__cur) + std::_Construct(&*__cur, __x); + } + catch(...) + { + std::_Destroy(__first, __cur); + __throw_exception_again; + } } - catch(...) - { - std::_Destroy(__first, __cur); - __throw_exception_again; - } - } + }; + + template<> + struct __uninitialized_fill_n + { + template + static void + uninitialized_fill_n(_ForwardIterator __first, _Size __n, + const _Tp& __x) + { std::fill_n(__first, __n, __x); } + }; /** * @brief Copies the value x into the range [first,first+n). @@ -182,10 +223,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std) { typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - if (__is_pod(_ValueType)) - std::fill_n(__first, __n, __x); - else - std::__uninitialized_fill_n_aux(__first, __n, __x); + + std::__uninitialized_fill_n<__is_pod(_ValueType)>:: + uninitialized_fill_n(__first, __n, __x); } // Extensions: versions of uninitialized_copy, uninitialized_fill, diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 93843f0a77e..f885f022a7d 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -210,11 +210,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) vector(size_type __n, const value_type& __value = value_type(), const allocator_type& __a = allocator_type()) : _Base(__n, __a) - { - std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value, - _M_get_Tp_allocator()); - this->_M_impl._M_finish = this->_M_impl._M_start + __n; - } + { _M_fill_initialize(__n, __value); } /** * @brief %Vector copy constructor. @@ -788,11 +784,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) this->_M_impl._M_start = _M_allocate(static_cast(__n)); this->_M_impl._M_end_of_storage = this->_M_impl._M_start + static_cast(__n); - std::__uninitialized_fill_n_a(this->_M_impl._M_start, - static_cast(__n), - __value, - _M_get_Tp_allocator()); - this->_M_impl._M_finish = this->_M_impl._M_end_of_storage; + _M_fill_initialize(static_cast(__n), __value); } // Called by the range constructor to implement [23.1.1]/9 @@ -831,6 +823,15 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) _M_get_Tp_allocator()); } + // Called by the first initialize_dispatch above and by the + // vector(n,value,a) constructor. + _M_fill_initialize(size_type __n, const value_type& __value) + { + std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value, + _M_get_Tp_allocator()); + this->_M_impl._M_finish = this->_M_impl._M_end_of_storage; + } + // Internal assign functions follow. The *_aux functions do the actual // assignment work for the range versions. diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/32158.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/32158.cc new file mode 100644 index 00000000000..1f9867e01b2 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/32158.cc @@ -0,0 +1,35 @@ +// Copyright (C) 2007 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 20.4.4 specialized algorithms + +// { dg-do compile } + +#include +#include + +// c++/32158 + +typedef std::pair MyPair; + +void +Alpha(MyPair* start, MyPair* end) +{ + MyPair my_pair(1, 2); + std::uninitialized_fill(start, end, my_pair); +}; diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc index 873c27f86ed..f076afef084 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 845 } +// { dg-error "no matching" "" { target *-*-* } 846 } // { dg-excess-errors "" } #include diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc index 79e339d3841..12aa0aea695 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no match" "" { target *-*-* } 622 } +// { dg-error "no matching" "" { target *-*-* } 787 } // { dg-excess-errors "" } #include diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc index bcc4f4755cc..1dd8d305e2e 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no match" "" { target *-*-* } 622 } +// { dg-error "no matching" "" { target *-*-* } 787 } // { dg-excess-errors "" } #include diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc index c82a5c4602d..be39739f005 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 886 } +// { dg-error "no matching" "" { target *-*-* } 887 } // { dg-excess-errors "" } #include