aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2007-12-26 21:58:49 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2007-12-26 21:58:49 +0000
commit5f6d5f0af6d71c61fc06e2d0435babc4a5a4502a (patch)
tree2945204b1ef2d8252e1890c5d77161474f662035 /libstdc++-v3
parent3dfb41c56409dcba9febba4cec9a42f1c2b0a3a3 (diff)
downloadgcc-5f6d5f0af6d71c61fc06e2d0435babc4a5a4502a.zip
gcc-5f6d5f0af6d71c61fc06e2d0435babc4a5a4502a.tar.gz
gcc-5f6d5f0af6d71c61fc06e2d0435babc4a5a4502a.tar.bz2
re PR libstdc++/34595 (std::copy copies the output iterator before assigning)
2007-12-26 Paolo Carlini <pcarlini@suse.de> PR libstdc++/34595 * include/bits/stl_algobase.h (struct __cm_assign): Remove. (struct __copy_move<true, false, _Category>, struct __copy_move<true, false, random_access_iterator_tag>, struct __copy_move_backward<true, false, _Category>, struct __copy_move_backward<true, false, random_access_iterator_tag>): Add. (struct __copy_move, struct __copy_move_backward, struct __copy_move<false, false, random_access_iterator_tag>, struct __copy_move_backward<false, false, random_access_iterator_tag>): Adjust. * testsuite/25_algorithms/copy/34595.C: New. From-SVN: r131188
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog15
-rw-r--r--libstdc++-v3/include/bits/stl_algobase.h107
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/copy/34595.C55
3 files changed, 146 insertions, 31 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index ae3ca7a..28a509e 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,18 @@
+2007-12-26 Paolo Carlini <pcarlini@suse.de>
+
+ PR libstdc++/34595
+ * include/bits/stl_algobase.h (struct __cm_assign): Remove.
+ (struct __copy_move<true, false, _Category>,
+ struct __copy_move<true, false, random_access_iterator_tag>,
+ struct __copy_move_backward<true, false, _Category>,
+ struct __copy_move_backward<true, false, random_access_iterator_tag>):
+ Add.
+ (struct __copy_move, struct __copy_move_backward,
+ struct __copy_move<false, false, random_access_iterator_tag>,
+ struct __copy_move_backward<false, false, random_access_iterator_tag>):
+ Adjust.
+ * testsuite/25_algorithms/copy/34595.C: New.
+
2007-12-26 Chris Fairles <chris.fairles@gmail.com>
Paolo Carlini <pcarlini@suse.de>
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index 52f2ca4..8f19453 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -295,34 +295,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{ return __it.base(); }
};
- // Used in __copy_move and __copy_move_backward below.
- template<bool _IsMove>
- struct __cm_assign
- {
- template<typename _IteratorL, typename _IteratorR>
- static void
- __a(_IteratorL __lhs, _IteratorR __rhs)
- { *__lhs = *__rhs; }
- };
-
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<>
- struct __cm_assign<true>
- {
- template<typename _IteratorL, typename _IteratorR>
- static void
- __a(_IteratorL __lhs, _IteratorR __rhs)
- { *__lhs = std::move(*__rhs); }
- };
-#endif
-
// All of these auxiliary structs serve two purposes. (1) Replace
// calls to copy with memmove whenever possible. (Memmove, not memcpy,
// because the input and output ranges are permitted to overlap.)
// (2) If we're using random access iterators, then write the loop as
// a for loop with an explicit count.
- template<bool _IsMove, bool, typename>
+ template<bool, bool, typename>
struct __copy_move
{
template<typename _II, typename _OI>
@@ -330,13 +309,47 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__copy_m(_II __first, _II __last, _OI __result)
{
for (; __first != __last; ++__result, ++__first)
- std::__cm_assign<_IsMove>::__a(__result, __first);
+ *__result = *__first;
+ return __result;
+ }
+ };
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Category>
+ struct __copy_move<true, false, _Category>
+ {
+ template<typename _II, typename _OI>
+ static _OI
+ __copy_m(_II __first, _II __last, _OI __result)
+ {
+ for (; __first != __last; ++__result, ++__first)
+ *__result = std::move(*__first);
+ return __result;
+ }
+ };
+#endif
+
+ template<>
+ struct __copy_move<false, false, random_access_iterator_tag>
+ {
+ template<typename _II, typename _OI>
+ static _OI
+ __copy_m(_II __first, _II __last, _OI __result)
+ {
+ typedef typename iterator_traits<_II>::difference_type _Distance;
+ for(_Distance __n = __last - __first; __n > 0; --__n)
+ {
+ *__result = *__first;
+ ++__first;
+ ++__result;
+ }
return __result;
}
};
- template<bool _IsMove, bool _IsSimple>
- struct __copy_move<_IsMove, _IsSimple, random_access_iterator_tag>
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<>
+ struct __copy_move<true, false, random_access_iterator_tag>
{
template<typename _II, typename _OI>
static _OI
@@ -345,13 +358,14 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
typedef typename iterator_traits<_II>::difference_type _Distance;
for(_Distance __n = __last - __first; __n > 0; --__n)
{
- std::__cm_assign<_IsMove>::__a(__result, __first);
+ *__result = std::move(*__first);
++__first;
++__result;
}
return __result;
}
};
+#endif
template<bool _IsMove>
struct __copy_move<_IsMove, true, random_access_iterator_tag>
@@ -489,7 +503,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
#define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::copy(_Tp, _Up, _Vp)
#endif
- template<bool _IsMove, bool, typename>
+ template<bool, bool, typename>
struct __copy_move_backward
{
template<typename _BI1, typename _BI2>
@@ -497,13 +511,28 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
{
while (__first != __last)
- std::__cm_assign<_IsMove>::__a(--__result, --__last);
+ *--__result = *--__last;
return __result;
}
};
- template<bool _IsMove, bool _IsSimple>
- struct __copy_move_backward<_IsMove, _IsSimple, random_access_iterator_tag>
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Category>
+ struct __copy_move_backward<true, false, _Category>
+ {
+ template<typename _BI1, typename _BI2>
+ static _BI2
+ __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
+ {
+ while (__first != __last)
+ *--__result = std::move(*--__last);
+ return __result;
+ }
+ };
+#endif
+
+ template<>
+ struct __copy_move_backward<false, false, random_access_iterator_tag>
{
template<typename _BI1, typename _BI2>
static _BI2
@@ -511,11 +540,27 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
typename iterator_traits<_BI1>::difference_type __n;
for (__n = __last - __first; __n > 0; --__n)
- std::__cm_assign<_IsMove>::__a(--__result, --__last);
+ *--__result = *--__last;
return __result;
}
};
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<>
+ struct __copy_move_backward<true, false, random_access_iterator_tag>
+ {
+ template<typename _BI1, typename _BI2>
+ static _BI2
+ __copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
+ {
+ typename iterator_traits<_BI1>::difference_type __n;
+ for (__n = __last - __first; __n > 0; --__n)
+ *--__result = std::move(*--__last);
+ return __result;
+ }
+ };
+#endif
+
template<bool _IsMove>
struct __copy_move_backward<_IsMove, true, random_access_iterator_tag>
{
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/34595.C b/libstdc++-v3/testsuite/25_algorithms/copy/34595.C
new file mode 100644
index 0000000..85bef55
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/copy/34595.C
@@ -0,0 +1,55 @@
+// 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 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 25.2.1 [lib.alg.copy] Copy.
+
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+class Counting_output_iterator
+: public std::iterator< std::output_iterator_tag, void, void, void, void >
+{
+ std::size_t c;
+public:
+ Counting_output_iterator() : c(0) {}
+ Counting_output_iterator& operator++() { return *this; }
+ Counting_output_iterator& operator*() { return *this; }
+
+ template <typename T>
+ void operator=(const T&) { ++c; }
+
+ std::size_t current_counter() const { return c; }
+};
+
+// libstdc++/34595
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ int t[10] = {0,};
+ Counting_output_iterator cnt;
+ std::size_t res = std::copy(t+0, t+5, cnt).current_counter();
+
+ VERIFY( res == 5 );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}