diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e6c277ccfd1..4ca96b2878a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,22 @@ +2009-12-24 Paolo Carlini + + * include/bits/stl_deque.h (copy_backward(_Deque_iterator, + _Deque_iterator, _Deque_iterator), move_backward(_Deque_iterator, + _Deque_iterator, _Deque_iterator)): Declare. + * include/bits/deque.tcc: Implement the latter. + * testsuite/performance/25_algorithms/ + copy_backward_deque_iterators.cc: New. + * testsuite/25_algorithms/move_backward/deque_iterators/1.cc: Likewise. + * testsuite/25_algorithms/copy_backward/deque_iterators/1.cc: Likewise. + * testsuite/23_containers/deque/requirements/dr438/assign_neg.cc: + Adjust dg-error line number. + * testsuite/23_containers/deque/requirements/dr438/insert_neg.cc: + Likewise. + * testsuite/23_containers/deque/requirements/dr438/ + constructor_1_neg.cc: Likewise. + * testsuite/23_containers/deque/requirements/dr438/ + constructor_2_neg.cc: Likewise. + 2009-12-23 Paolo Carlini * testsuite/25_algorithms/copy/5.cc: Move... diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc index 968fc0051c5..cde067cf382 100644 --- a/libstdc++-v3/include/bits/deque.tcc +++ b/libstdc++-v3/include/bits/deque.tcc @@ -865,11 +865,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) _Deque_iterator<_Tp, _Tp&, _Tp*> __result) { typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; + typedef typename _Self::difference_type difference_type; - typename _Self::difference_type __len = __last - __first; + difference_type __len = __last - __first; while (__len > 0) { - typename _Self::difference_type __clen + const difference_type __clen = std::min(__len, std::min(__first._M_last - __first._M_cur, __result._M_last - __result._M_cur)); std::copy(__first._M_cur, __first._M_cur + __clen, __result._M_cur); @@ -880,6 +881,45 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) return __result; } + template + _Deque_iterator<_Tp, _Tp&, _Tp*> + copy_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first, + _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last, + _Deque_iterator<_Tp, _Tp&, _Tp*> __result) + { + typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; + typedef typename _Self::difference_type difference_type; + + difference_type __len = __last - __first; + while (__len > 0) + { + difference_type __llen = __last._M_cur - __last._M_first; + _Tp* __lend = __last._M_cur; + + difference_type __rlen = __result._M_cur - __result._M_first; + _Tp* __rend = __result._M_cur; + + if (!__llen) + { + __llen = _Self::_S_buffer_size(); + __lend = *(__last._M_node - 1) + __llen; + } + if (!__rlen) + { + __rlen = _Self::_S_buffer_size(); + __rend = *(__result._M_node - 1) + __rlen; + } + + const difference_type __clen = std::min(__len, + std::min(__llen, __rlen)); + std::copy_backward(__lend - __clen, __lend, __rend); + __last -= __clen; + __result -= __clen; + __len -= __clen; + } + return __result; + } + #ifdef __GXX_EXPERIMENTAL_CXX0X__ template _Deque_iterator<_Tp, _Tp&, _Tp*> @@ -888,11 +928,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) _Deque_iterator<_Tp, _Tp&, _Tp*> __result) { typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; + typedef typename _Self::difference_type difference_type; - typename _Self::difference_type __len = __last - __first; + difference_type __len = __last - __first; while (__len > 0) { - const typename _Self::difference_type __clen + const difference_type __clen = std::min(__len, std::min(__first._M_last - __first._M_cur, __result._M_last - __result._M_cur)); std::move(__first._M_cur, __first._M_cur + __clen, __result._M_cur); @@ -902,6 +943,45 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) } return __result; } + + template + _Deque_iterator<_Tp, _Tp&, _Tp*> + move_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first, + _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last, + _Deque_iterator<_Tp, _Tp&, _Tp*> __result) + { + typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; + typedef typename _Self::difference_type difference_type; + + difference_type __len = __last - __first; + while (__len > 0) + { + difference_type __llen = __last._M_cur - __last._M_first; + _Tp* __lend = __last._M_cur; + + difference_type __rlen = __result._M_cur - __result._M_first; + _Tp* __rend = __result._M_cur; + + if (!__llen) + { + __llen = _Self::_S_buffer_size(); + __lend = *(__last._M_node - 1) + __llen; + } + if (!__rlen) + { + __rlen = _Self::_S_buffer_size(); + __rend = *(__result._M_node - 1) + __rlen; + } + + const difference_type __clen = std::min(__len, + std::min(__llen, __rlen)); + std::move_backward(__lend - __clen, __lend, __rend); + __last -= __clen; + __result -= __clen; + __len -= __clen; + } + return __result; + } #endif _GLIBCXX_END_NESTED_NAMESPACE diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index 99105ebdcd4..647d5476874 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -370,6 +370,23 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) _Deque_iterator<_Tp, const _Tp&, const _Tp*>(__last), __result); } + template + _Deque_iterator<_Tp, _Tp&, _Tp*> + copy_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*>, + _Deque_iterator<_Tp, const _Tp&, const _Tp*>, + _Deque_iterator<_Tp, _Tp&, _Tp*>); + + template + inline _Deque_iterator<_Tp, _Tp&, _Tp*> + copy_backward(_Deque_iterator<_Tp, _Tp&, _Tp*> __first, + _Deque_iterator<_Tp, _Tp&, _Tp*> __last, + _Deque_iterator<_Tp, _Tp&, _Tp*> __result) + { return std::copy_backward(_Deque_iterator<_Tp, + const _Tp&, const _Tp*>(__first), + _Deque_iterator<_Tp, + const _Tp&, const _Tp*>(__last), + __result); } + #ifdef __GXX_EXPERIMENTAL_CXX0X__ template _Deque_iterator<_Tp, _Tp&, _Tp*> @@ -385,6 +402,23 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D) { return std::move(_Deque_iterator<_Tp, const _Tp&, const _Tp*>(__first), _Deque_iterator<_Tp, const _Tp&, const _Tp*>(__last), __result); } + + template + _Deque_iterator<_Tp, _Tp&, _Tp*> + move_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*>, + _Deque_iterator<_Tp, const _Tp&, const _Tp*>, + _Deque_iterator<_Tp, _Tp&, _Tp*>); + + template + inline _Deque_iterator<_Tp, _Tp&, _Tp*> + move_backward(_Deque_iterator<_Tp, _Tp&, _Tp*> __first, + _Deque_iterator<_Tp, _Tp&, _Tp*> __last, + _Deque_iterator<_Tp, _Tp&, _Tp*> __result) + { return std::move_backward(_Deque_iterator<_Tp, + const _Tp&, const _Tp*>(__first), + _Deque_iterator<_Tp, + const _Tp&, const _Tp*>(__last), + __result); } #endif /** diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc index b022e14a609..0b948aed7fb 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc @@ -18,7 +18,7 @@ // . // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1534 } +// { dg-error "no matching" "" { target *-*-* } 1568 } // { dg-excess-errors "" } #include diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc index a43f2c707a5..2f88aa8eb80 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc @@ -18,7 +18,7 @@ // . // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1473 } +// { dg-error "no matching" "" { target *-*-* } 1507 } // { dg-excess-errors "" } #include diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc index 71a4ceb3c69..3895d1e8758 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc @@ -18,7 +18,7 @@ // . // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1473 } +// { dg-error "no matching" "" { target *-*-* } 1507 } // { dg-excess-errors "" } #include diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc index 8709c4658d2..50d8d4657a1 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc @@ -18,7 +18,7 @@ // . // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1618 } +// { dg-error "no matching" "" { target *-*-* } 1652 } // { dg-excess-errors "" } #include diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_backward/deque_iterators/1.cc b/libstdc++-v3/testsuite/25_algorithms/copy_backward/deque_iterators/1.cc new file mode 100644 index 00000000000..57405cc80e8 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy_backward/deque_iterators/1.cc @@ -0,0 +1,52 @@ +// 2009-12-24 Paolo Carlini +// +// 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 Pred 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 +// . + +#include +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + using namespace std; + + deque data(200); + for (unsigned i = 0; i < data.size(); ++i) + data[i] = i; + + const deque data_1(data.size(), -1); + + for (unsigned i = 0; i < data.size(); i += 2) + for (unsigned j = i; j <= data.size(); j += 3) + for (unsigned k = 0; k + (j - i) <= data.size(); k += 5) + { + deque d(data.size(), -1); + copy_backward(data.begin() + i, data.begin() + j, + d.begin() + k + (j - i)); + + VERIFY( equal(data.begin() + i, data.begin() + j, + d.begin() + k) ); + VERIFY( equal(d.begin(), d.begin() + k, data_1.begin()) ); + VERIFY( equal(d.begin() + k + (j - i), d.end(), data_1.begin()) ); + } +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/move_backward/deque_iterators/1.cc b/libstdc++-v3/testsuite/25_algorithms/move_backward/deque_iterators/1.cc new file mode 100644 index 00000000000..9a8ba71206f --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/move_backward/deque_iterators/1.cc @@ -0,0 +1,54 @@ +// { dg-options "-std=gnu++0x" } + +// 2009-12-24 Paolo Carlini +// +// 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 Pred 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 +// . + +#include +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + using namespace std; + + deque data(200); + for (unsigned i = 0; i < data.size(); ++i) + data[i] = i; + + const deque data_1(data.size(), -1); + + for (unsigned i = 0; i < data.size(); i += 2) + for (unsigned j = i; j <= data.size(); j += 3) + for (unsigned k = 0; k + (j - i) <= data.size(); k += 5) + { + deque d(data.size(), -1); + move_backward(data.begin() + i, data.begin() + j, + d.begin() + k + (j - i)); + + VERIFY( equal(data.begin() + i, data.begin() + j, + d.begin() + k) ); + VERIFY( equal(d.begin(), d.begin() + k, data_1.begin()) ); + VERIFY( equal(d.begin() + k + (j - i), d.end(), data_1.begin()) ); + } +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/performance/25_algorithms/copy_backward_deque_iterators.cc b/libstdc++-v3/testsuite/performance/25_algorithms/copy_backward_deque_iterators.cc new file mode 100644 index 00000000000..c7dbdc006c2 --- /dev/null +++ b/libstdc++-v3/testsuite/performance/25_algorithms/copy_backward_deque_iterators.cc @@ -0,0 +1,40 @@ +// 2009-24-12 Paolo Carlini +// +// 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 Pred 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 +// . + +#include +#include + +int main() +{ + using namespace __gnu_test; + + time_counter time; + resource_counter resource; + + const std::deque data(3000, 3); + + std::deque d(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::copy_backward(data.begin(), data.begin() + j, d.end()); + stop_counters(time, resource); + report_performance(__FILE__, "", time, resource); + + return 0; +}