From 3089d5a4191be0a88dfe84ba844db83d166aafe6 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 8 Feb 2006 21:51:55 +0000 Subject: [PATCH] PR libstdc++/26133 (DR 241, [WP]) 2006-02-08 Paolo Carlini PR libstdc++/26133 (DR 241, [WP]) * include/bits/stl_algo.h (__unique_copy(,,, forward_iterator_tag, output_iterator_tag), __unique_copy(,,, input_iterator_tag, output_iterator_tag), __unique_copy(,,, input_iterator_tag, forward_iterator_tag), and predicated counterparts): Add. (__unique_copy(,,, output_iterator_tag), __unique_copy(,,, forward_iterator_tag), and predicated counterparts): Remove. (unique_copy): Adjust, dispatch to the three helpers above. * testsuite/25_algorithms/unique_copy/2.cc: New. * testsuite/25_algorithms/unique_copy/26133.cc: Likewise. * testsuite/25_algorithms/unique_copy/3.cc: Likewise. * docs/html/ext/howto.html: Add an entry for DR 241. * testsuite/25_algorithms/unique_copy/1.cc: Minor cosmetic changes. From-SVN: r110772 --- libstdc++-v3/ChangeLog | 17 ++ libstdc++-v3/docs/html/ext/howto.html | 7 + libstdc++-v3/include/bits/stl_algo.h | 163 +++++++++++++----- .../testsuite/25_algorithms/unique_copy/1.cc | 22 +-- .../testsuite/25_algorithms/unique_copy/2.cc | 85 +++++++++ .../25_algorithms/unique_copy/26133.cc | 51 ++++++ .../testsuite/25_algorithms/unique_copy/3.cc | 93 ++++++++++ 7 files changed, 382 insertions(+), 56 deletions(-) create mode 100644 libstdc++-v3/testsuite/25_algorithms/unique_copy/2.cc create mode 100644 libstdc++-v3/testsuite/25_algorithms/unique_copy/26133.cc create mode 100644 libstdc++-v3/testsuite/25_algorithms/unique_copy/3.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 9341fd1b51a..84e399303c8 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,20 @@ +2006-02-08 Paolo Carlini + + PR libstdc++/26133 (DR 241, [WP]) + * include/bits/stl_algo.h (__unique_copy(,,, forward_iterator_tag, + output_iterator_tag), __unique_copy(,,, input_iterator_tag, + output_iterator_tag), __unique_copy(,,, input_iterator_tag, + forward_iterator_tag), and predicated counterparts): Add. + (__unique_copy(,,, output_iterator_tag), __unique_copy(,,, + forward_iterator_tag), and predicated counterparts): Remove. + (unique_copy): Adjust, dispatch to the three helpers above. + * testsuite/25_algorithms/unique_copy/2.cc: New. + * testsuite/25_algorithms/unique_copy/26133.cc: Likewise. + * testsuite/25_algorithms/unique_copy/3.cc: Likewise. + * docs/html/ext/howto.html: Add an entry for DR 241. + + * testsuite/25_algorithms/unique_copy/1.cc: Minor cosmetic changes. + 2006-02-07 Jakub Jelinek Benjamin Kosnik diff --git a/libstdc++-v3/docs/html/ext/howto.html b/libstdc++-v3/docs/html/ext/howto.html index bc0b358b9f3..6aaf994ae50 100644 --- a/libstdc++-v3/docs/html/ext/howto.html +++ b/libstdc++-v3/docs/html/ext/howto.html @@ -413,6 +413,13 @@ However, no specification is given what this constructor should do. +
241: + Does unique_copy() require CopyConstructible and Assignable? +
+
Add an helper for forward_iterator/output_iterator, fix the existing + one for input_iterator/output_iterator not to rely on Assignability. +
+
243: get and getline when sentry reports failure
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index 355d859a901..d5c8f9ddde6 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -1,6 +1,7 @@ // Algorithm implementation -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 +// 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 @@ -1294,23 +1295,23 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * @if maint * This is an uglified unique_copy(_InputIterator, _InputIterator, * _OutputIterator) - * overloaded for output iterators. + * overloaded for forward iterators and output iterator as result. * @endif */ - template + template _OutputIterator - __unique_copy(_InputIterator __first, _InputIterator __last, + __unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, - output_iterator_tag) + forward_iterator_tag, output_iterator_tag) { // concept requirements -- taken care of in dispatching function - typename iterator_traits<_InputIterator>::value_type __value = *__first; - *__result = __value; - while (++__first != __last) - if (!(__value == *__first)) + _ForwardIterator __next = __first; + *__result = *__first; + while (++__next != __last) + if (!(*__first == *__next)) { - __value = *__first; - *++__result = __value; + __first = __next; + *++__result = *__first; } return ++__result; } @@ -1319,14 +1320,43 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * @if maint * This is an uglified unique_copy(_InputIterator, _InputIterator, * _OutputIterator) - * overloaded for forward iterators. + * overloaded for input iterators and output iterator as result. + * @endif + */ + template + _OutputIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, + input_iterator_tag, output_iterator_tag) + { + // concept requirements -- taken care of in dispatching function + *__result = *__first; + while (true) + { + typename + iterator_traits<_InputIterator>::value_type __value = *__first; + + if (++__first == __last) + break; + + if (!(__value == *__first)) + *++__result = *__first; + } + return ++__result; + } + + /** + * @if maint + * This is an uglified unique_copy(_InputIterator, _InputIterator, + * _OutputIterator) + * overloaded for input iterators and forward iterator as result. * @endif */ template _ForwardIterator __unique_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result, - forward_iterator_tag) + input_iterator_tag, forward_iterator_tag) { // concept requirements -- taken care of in dispatching function *__result = *__first; @@ -1341,29 +1371,28 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * This is an uglified * unique_copy(_InputIterator, _InputIterator, _OutputIterator, * _BinaryPredicate) - * overloaded for output iterators. + * overloaded for forward iterators and output iterator as result. * @endif */ - template _OutputIterator - __unique_copy(_InputIterator __first, _InputIterator __last, - _OutputIterator __result, - _BinaryPredicate __binary_pred, - output_iterator_tag) + __unique_copy(_ForwardIterator __first, _ForwardIterator __last, + _OutputIterator __result, _BinaryPredicate __binary_pred, + forward_iterator_tag, output_iterator_tag) { // concept requirements -- iterators already checked __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, - typename iterator_traits<_InputIterator>::value_type, - typename iterator_traits<_InputIterator>::value_type>) + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_ForwardIterator>::value_type>) - typename iterator_traits<_InputIterator>::value_type __value = *__first; - *__result = __value; - while (++__first != __last) - if (!__binary_pred(__value, *__first)) + _ForwardIterator __next = __first; + *__result = *__first; + while (++__next != __last) + if (!__binary_pred(*__first, *__next)) { - __value = *__first; - *++__result = __value; + __first = __next; + *++__result = *__first; } return ++__result; } @@ -1373,25 +1402,60 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * This is an uglified * unique_copy(_InputIterator, _InputIterator, _OutputIterator, * _BinaryPredicate) - * overloaded for forward iterators. + * overloaded for input iterators and output iterator as result. + * @endif + */ + template + _OutputIterator + __unique_copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryPredicate __binary_pred, + input_iterator_tag, output_iterator_tag) + { + // concept requirements -- iterators already checked + __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, + typename iterator_traits<_InputIterator>::value_type, + typename iterator_traits<_InputIterator>::value_type>) + + *__result = *__first; + while (true) + { + typename + iterator_traits<_InputIterator>::value_type __value = *__first; + + if (++__first == __last) + break; + + if (!__binary_pred(__value, *__first)) + *++__result = *__first; + } + return ++__result; + } + + /** + * @if maint + * This is an uglified + * unique_copy(_InputIterator, _InputIterator, _OutputIterator, + * _BinaryPredicate) + * overloaded for input iterators and forward iterator as result. * @endif */ template _ForwardIterator __unique_copy(_InputIterator __first, _InputIterator __last, - _ForwardIterator __result, - _BinaryPredicate __binary_pred, - forward_iterator_tag) + _ForwardIterator __result, _BinaryPredicate __binary_pred, + input_iterator_tag, forward_iterator_tag) { // concept requirements -- iterators already checked __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate, - typename iterator_traits<_ForwardIterator>::value_type, - typename iterator_traits<_InputIterator>::value_type>) + typename iterator_traits<_ForwardIterator>::value_type, + typename iterator_traits<_InputIterator>::value_type>) *__result = *__first; while (++__first != __last) - if (!__binary_pred(*__result, *__first)) *++__result = *__first; + if (!__binary_pred(*__result, *__first)) + *++__result = *__first; return ++__result; } @@ -1407,6 +1471,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * from groups of consecutive elements that compare equal. * unique_copy() is stable, so the relative order of elements that are * copied is unchanged. + * + * @if maint + * _GLIBCXX_RESOLVE_LIB_DEFECTS + * DR 241. Does unique_copy() require CopyConstructible and Assignable? + * @endif */ template inline _OutputIterator @@ -1421,11 +1490,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - typedef typename iterator_traits<_OutputIterator>::iterator_category - _IterType; - - if (__first == __last) return __result; - return std::__unique_copy(__first, __last, __result, _IterType()); + if (__first == __last) + return __result; + return std::__unique_copy(__first, __last, __result, + std::__iterator_category(__first), + std::__iterator_category(__result)); } /** @@ -1442,6 +1511,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * true. * unique_copy() is stable, so the relative order of elements that are * copied is unchanged. + * + * @if maint + * _GLIBCXX_RESOLVE_LIB_DEFECTS + * DR 241. Does unique_copy() require CopyConstructible and Assignable? + * @endif */ template @@ -1456,12 +1530,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std) typename iterator_traits<_InputIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - typedef typename iterator_traits<_OutputIterator>::iterator_category - _IterType; - - if (__first == __last) return __result; - return std::__unique_copy(__first, __last, __result, - __binary_pred, _IterType()); + if (__first == __last) + return __result; + return std::__unique_copy(__first, __last, __result, __binary_pred, + std::__iterator_category(__first), + std::__iterator_category(__result)); } /** diff --git a/libstdc++-v3/testsuite/25_algorithms/unique_copy/1.cc b/libstdc++-v3/testsuite/25_algorithms/unique_copy/1.cc index 29c4e26c478..06a38f8fee1 100644 --- a/libstdc++-v3/testsuite/25_algorithms/unique_copy/1.cc +++ b/libstdc++-v3/testsuite/25_algorithms/unique_copy/1.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2005 Free Software Foundation, Inc. +// Copyright (C) 2005, 2006 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 @@ -16,7 +16,7 @@ // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, // USA. -// 25.5.8 [lib.alg.unique] +// 25.2.8 [lib.alg.unique] #include #include @@ -26,7 +26,7 @@ using __gnu_test::test_container; using __gnu_test::input_iterator_wrapper; using __gnu_test::forward_iterator_wrapper; using __gnu_test::output_iterator_wrapper; -using std::unique; +using std::unique_copy; typedef test_container Icontainer; typedef test_container Fcontainer; @@ -41,7 +41,7 @@ test1() bool test __attribute__((unused)) = true; Icontainer con1(array1, array1); Ocontainer con2(array2, array2); - VERIFY(unique_copy(con1.begin(), con1.end(), con2.begin()).ptr == array2); + VERIFY( unique_copy(con1.begin(), con1.end(), con2.begin()).ptr == array2 ); } void @@ -50,9 +50,9 @@ test2() bool test __attribute__((unused)) = true; Icontainer con1(array1, array1 + 6); Ocontainer con2(array2, array2 + 2); - VERIFY(unique_copy(con1.begin(), con1.end(), con2.begin()).ptr - == array2 + 2); - VERIFY(array2[0] == 0 && array2[1] == 1); + VERIFY( unique_copy(con1.begin(), con1.end(), con2.begin()).ptr + == array2 + 2 ); + VERIFY( array2[0] == 0 && array2[1] == 1 ); } void @@ -61,7 +61,7 @@ test3() bool test __attribute__((unused)) = true; Icontainer con1(array1, array1); Fcontainer con2(array2, array2); - VERIFY(unique_copy(con1.begin(), con1.end(), con2.begin()).ptr == array2); + VERIFY( unique_copy(con1.begin(), con1.end(), con2.begin()).ptr == array2 ); } void @@ -70,9 +70,9 @@ test4() bool test __attribute__((unused)) = true; Icontainer con1(array1, array1 + 6); Fcontainer con2(array2, array2 + 2); - VERIFY(unique_copy(con1.begin(), con1.end(), con2.begin()).ptr - == array2 + 2); - VERIFY(array2[0] == 0 && array2[1] == 1); + VERIFY( unique_copy(con1.begin(), con1.end(), con2.begin()).ptr + == array2 + 2 ); + VERIFY( array2[0] == 0 && array2[1] == 1 ); } int diff --git a/libstdc++-v3/testsuite/25_algorithms/unique_copy/2.cc b/libstdc++-v3/testsuite/25_algorithms/unique_copy/2.cc new file mode 100644 index 00000000000..13500916542 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/unique_copy/2.cc @@ -0,0 +1,85 @@ +// Copyright (C) 2006 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. + +// 25.2.8 [lib.alg.unique] + +#include +#include +#include + +using __gnu_test::test_container; +using __gnu_test::forward_iterator_wrapper; +using __gnu_test::output_iterator_wrapper; +using std::unique_copy; +using std::equal_to; + +typedef test_container Fcontainer; +typedef test_container Ocontainer; + +int array1[] = {0, 0, 0, 1, 1, 1}; +int array2[2]; + +void +test1() +{ + bool test __attribute__((unused)) = true; + Fcontainer con1(array1, array1); + Ocontainer con2(array2, array2); + VERIFY( unique_copy(con1.begin(), con1.end(), con2.begin()).ptr == array2 ); +} + +void +test2() +{ + bool test __attribute__((unused)) = true; + Fcontainer con1(array1, array1 + 6); + Ocontainer con2(array2, array2 + 2); + VERIFY( unique_copy(con1.begin(), con1.end(), con2.begin()).ptr + == array2 + 2 ); + VERIFY( array2[0] == 0 && array2[1] == 1 ); +} + +void +test3() +{ + bool test __attribute__((unused)) = true; + Fcontainer con1(array1, array1); + Ocontainer con2(array2, array2); + VERIFY( unique_copy(con1.begin(), con1.end(), con2.begin(), + equal_to()).ptr == array2 ); +} + +void +test4() +{ + bool test __attribute__((unused)) = true; + Fcontainer con1(array1, array1 + 6); + Ocontainer con2(array2, array2 + 2); + VERIFY( unique_copy(con1.begin(), con1.end(), con2.begin(), + equal_to()).ptr == array2 + 2 ); + VERIFY( array2[0] == 0 && array2[1] == 1 ); +} + +int +main() +{ + test1(); + test2(); + test3(); + test4(); +} diff --git a/libstdc++-v3/testsuite/25_algorithms/unique_copy/26133.cc b/libstdc++-v3/testsuite/25_algorithms/unique_copy/26133.cc new file mode 100644 index 00000000000..2c77667a12c --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/unique_copy/26133.cc @@ -0,0 +1,51 @@ +// Copyright (C) 2006 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. + +#include +#include +#include +#include + +struct no_assign +{ + int const x; + no_assign() : x(23) { } + operator int() const { return x; } +}; + +// libstdc++/26133 +void test01() +{ + bool test __attribute__((unused)) = true; + std::ostringstream oss1, oss2; + + no_assign in[4]; + + std::unique_copy(in, in + 4, std::ostream_iterator(oss1, "\n")); + VERIFY( oss1.str() == "23\n" ); + + std::unique_copy(in, in + 4, std::ostream_iterator(oss2, "\n"), + std::equal_to()); + VERIFY( oss2.str() == "23\n" ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/unique_copy/3.cc b/libstdc++-v3/testsuite/25_algorithms/unique_copy/3.cc new file mode 100644 index 00000000000..2245821f7c1 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/unique_copy/3.cc @@ -0,0 +1,93 @@ +// Copyright (C) 2006 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. + +// 25.2.8 [lib.alg.unique] + +#include +#include +#include + +using __gnu_test::test_container; +using __gnu_test::input_iterator_wrapper; +using __gnu_test::output_iterator_wrapper; +using std::unique_copy; +using std::equal_to; + +struct no_assign +{ + int const x; + no_assign() : x(23) { } + no_assign(int val) : x(val) { } + operator int() const { return x; } +}; + +typedef test_container Icontainer; +typedef test_container Ocontainer; + +no_assign array1[] = {0, 0, 0, 1, 1, 1}; +int array2[2]; + +void +test1() +{ + bool test __attribute__((unused)) = true; + Icontainer con1(array1, array1); + Ocontainer con2(array2, array2); + VERIFY( unique_copy(con1.begin(), con1.end(), con2.begin()).ptr == array2 ); +} + +void +test2() +{ + bool test __attribute__((unused)) = true; + Icontainer con1(array1, array1 + 6); + Ocontainer con2(array2, array2 + 2); + VERIFY( unique_copy(con1.begin(), con1.end(), con2.begin()).ptr + == array2 + 2 ); + VERIFY( array2[0] == 0 && array2[1] == 1 ); +} + +void +test3() +{ + bool test __attribute__((unused)) = true; + Icontainer con1(array1, array1); + Ocontainer con2(array2, array2); + VERIFY( unique_copy(con1.begin(), con1.end(), con2.begin(), + equal_to()).ptr == array2 ); +} + +void +test4() +{ + bool test __attribute__((unused)) = true; + Icontainer con1(array1, array1 + 6); + Ocontainer con2(array2, array2 + 2); + VERIFY( unique_copy(con1.begin(), con1.end(), con2.begin(), + equal_to()).ptr == array2 + 2 ); + VERIFY( array2[0] == 0 && array2[1] == 1 ); +} + +int +main() +{ + test1(); + test2(); + test3(); + test4(); +}