diff options
author | Chris Jefferson <chris@bubblescope.net> | 2009-08-29 19:27:05 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2009-08-29 19:27:05 +0000 |
commit | 55dd8445566670fbfd037d6d586875b68942fc60 (patch) | |
tree | d984898488471f4f866a2e225cabb539f07d3485 | |
parent | f1588ca05296a29bb2322b956aaeebd539d33c5d (diff) | |
download | gcc-55dd8445566670fbfd037d6d586875b68942fc60.zip gcc-55dd8445566670fbfd037d6d586875b68942fc60.tar.gz gcc-55dd8445566670fbfd037d6d586875b68942fc60.tar.bz2 |
move.h (_GLIBCXX_FORWARD): Add.
2009-08-29 Chris Jefferson <chris@bubblescope.net>
* include/bits/move.h (_GLIBCXX_FORWARD): Add.
* include/bits/stl_uninitialized.h (__uninitialized_construct_range):
Add.
* include/bits/stl_tempbuf.h (_Temporary_buffer::
_Temporary_buffer(_ForwardIterator, _ForwardIterator)): Use the latter.
* include/bits/stl_construct.h (_Construct(_T1*, _T2&&)): Add in
C++0x mode.
* testsuite/util/testsuite_hooks.h (operator<(const copy_tracker&,
const copy_tracker&)): Add.
* testsuite/25_algorithms/stable_partition/mem_check.cc: New.
* testsuite/25_algorithms/stable_sort/mem_check.cc: Likewise.
From-SVN: r151207
-rw-r--r-- | libstdc++-v3/ChangeLog | 18 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/move.h | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_construct.h | 7 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_tempbuf.h | 5 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_uninitialized.h | 62 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/25_algorithms/stable_partition/mem_check.cc | 71 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/25_algorithms/stable_sort/mem_check.cc | 103 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/util/testsuite_hooks.h | 4 |
8 files changed, 267 insertions, 5 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 868f541..818d3c3 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,17 @@ +2009-08-29 Chris Jefferson <chris@bubblescope.net> + + * include/bits/move.h (_GLIBCXX_FORWARD): Add. + * include/bits/stl_uninitialized.h (__uninitialized_construct_range): + Add. + * include/bits/stl_tempbuf.h (_Temporary_buffer:: + _Temporary_buffer(_ForwardIterator, _ForwardIterator)): Use the latter. + * include/bits/stl_construct.h (_Construct(_T1*, _T2&&)): Add in + C++0x mode. + * testsuite/util/testsuite_hooks.h (operator<(const copy_tracker&, + const copy_tracker&)): Add. + * testsuite/25_algorithms/stable_partition/mem_check.cc: New. + * testsuite/25_algorithms/stable_sort/mem_check.cc: Likewise. + 2009-08-26 Benjamin Kosnik <bkoz@redhat.com> * config/abi/pre/gnu.ver: Fixups for string member functions. @@ -134,8 +148,8 @@ types. (__unguarded_linear_insert): Assume always inserting value at __last. (__unguarded_partition): Take pivot by reference. - (__introsort_loop, __introselect) : Use __unguarded_partition_pivot. - * testsuite/25_algorithms/nth_element/moveable.cc : Enable. + (__introsort_loop, __introselect): Use __unguarded_partition_pivot. + * testsuite/25_algorithms/nth_element/moveable.cc: Enable. 2009-08-23 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h index e52dec8..668e64c 100644 --- a/libstdc++-v3/include/bits/move.h +++ b/libstdc++-v3/include/bits/move.h @@ -84,8 +84,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std) _GLIBCXX_END_NAMESPACE #define _GLIBCXX_MOVE(_Tp) std::move(_Tp) +#define _GLIBCXX_FORWARD(_Tp, __val) std::forward<_Tp>(__val) #else #define _GLIBCXX_MOVE(_Tp) (_Tp) +#define _GLIBCXX_FORWARD(_Tp, __val) (__val) #endif _GLIBCXX_BEGIN_NAMESPACE(std) diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h index 9df37fe..0366eec 100644 --- a/libstdc++-v3/include/bits/stl_construct.h +++ b/libstdc++-v3/include/bits/stl_construct.h @@ -67,11 +67,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std) */ template<typename _T1, typename _T2> inline void +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + // Allow perfect forwarding + _Construct(_T1* __p, _T2&& __value) +#else _Construct(_T1* __p, const _T2& __value) +#endif { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 402. wrong new expression in [some_]allocator::construct - ::new(static_cast<void*>(__p)) _T1(__value); + ::new(static_cast<void*>(__p)) _T1(_GLIBCXX_FORWARD(_T2, __value)); } /** diff --git a/libstdc++-v3/include/bits/stl_tempbuf.h b/libstdc++-v3/include/bits/stl_tempbuf.h index a3b0810..2b88791 100644 --- a/libstdc++-v3/include/bits/stl_tempbuf.h +++ b/libstdc++-v3/include/bits/stl_tempbuf.h @@ -188,8 +188,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std) value_type>(_M_original_len)); _M_buffer = __p.first; _M_len = __p.second; - if (!__is_pod(_Tp) && _M_len > 0) - std::uninitialized_fill_n(_M_buffer, _M_len, *__first); + if(_M_buffer) + std::__uninitialized_construct_range(_M_buffer, _M_buffer + _M_len, + *__first); } __catch(...) { diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h index 11a66c7..bd04ae9 100644 --- a/libstdc++-v3/include/bits/stl_uninitialized.h +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -173,6 +173,68 @@ _GLIBCXX_BEGIN_NAMESPACE(std) template<bool> + struct __uninitialized_construct_range_dispatch + { + template<typename _ForwardIterator, typename _Tp> + static void + __ucr(_ForwardIterator __first, _ForwardIterator __last, + _Tp& __value) + { + if(__first == __last) + return; + + _ForwardIterator __cur = __first; + __try + { + std::_Construct(&*__first, _GLIBCXX_MOVE(__value)); + _ForwardIterator __prev = __cur; + ++__cur; + for(; __cur != __last; ++__cur, ++__prev) + std::_Construct(&*__cur, _GLIBCXX_MOVE(*__prev)); + __value = _GLIBCXX_MOVE(*__prev); + } + __catch(...) + { + std::_Destroy(__first, __cur); + __throw_exception_again; + } + } + }; + + template<> + struct __uninitialized_construct_range_dispatch<true> + { + template<typename _ForwardIterator, typename _Tp> + static void + __ucr(_ForwardIterator, _ForwardIterator, _Tp&) { } + }; + + // Constructs objects in the range [first, last). + // Note that while these new objects will take valid values, + // their exact value is not defined. In particular they may + // be 'moved from'. + // + // While __value may altered during this algorithm, it will have + // the same value when the algorithm finishes, unless one of the + // constructions throws. + // + // Requirements: _ForwardIterator::value_type(_Tp&&) is valid. + template<typename _ForwardIterator, typename _Tp> + inline void + __uninitialized_construct_range(_ForwardIterator __first, + _ForwardIterator __last, + _Tp& __value) + { + typedef typename std::iterator_traits<_ForwardIterator>::value_type + _ValueType; + + std::__uninitialized_construct_range_dispatch< + __has_trivial_constructor(_ValueType)>:: + __ucr(__first, __last, __value); + } + + + template<bool> struct __uninitialized_fill_n { template<typename _ForwardIterator, typename _Size, typename _Tp> diff --git a/libstdc++-v3/testsuite/25_algorithms/stable_partition/mem_check.cc b/libstdc++-v3/testsuite/25_algorithms/stable_partition/mem_check.cc new file mode 100644 index 0000000..81d816d --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/stable_partition/mem_check.cc @@ -0,0 +1,71 @@ +// Copyright (C) 2009 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.2.12 [lib.alg.partitions] Partitions. + +#include <algorithm> +#include <testsuite_hooks.h> +#include <testsuite_iterators.h> + +using __gnu_test::test_container; +using __gnu_test::random_access_iterator_wrapper; +using __gnu_test::copy_tracker; +using __gnu_test::copy_constructor; +using __gnu_test::assignment_operator; +using __gnu_test::destructor; + +typedef test_container<copy_tracker, random_access_iterator_wrapper> Container; + +const int A[] = {10, 20, 1, 11, 2, 21, 28, 29, 12, 35, 15, 27, 6, 16, 7, + 25, 17, 8, 23, 18, 9, 19, 24, 30, 13, 4, 14, 22, 26}; + +bool even(const copy_tracker& ct) +{ return ct.id() < 19; } + +void +test1(int throw_count) +{ + bool test __attribute__((unused)) = true; + + copy_tracker vals[30]; + for(int i = 0; i < 30; ++i) + vals[i] = A[i]; + + Container con(vals, vals + 30); + copy_tracker::reset(); + copy_constructor::throw_on(throw_count); + int throw_occurred = 0; + try + { + std::stable_partition(con.begin(), con.end(), even); + } + catch(...) + { + throw_occurred = 1; + } + + // If a throw occurred in copy_constructor, we will end up with one more + // copy_construct than destructor. + VERIFY( destructor::count() == copy_constructor::count() - throw_occurred ); +} + +int main() +{ + for(int i = 0; i < 32; ++i) + test1(i); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/stable_sort/mem_check.cc b/libstdc++-v3/testsuite/25_algorithms/stable_sort/mem_check.cc new file mode 100644 index 0000000..78c14b4 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/stable_sort/mem_check.cc @@ -0,0 +1,103 @@ +// Copyright (C) 2009 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 <algorithm> +#include <testsuite_hooks.h> +#include <testsuite_iterators.h> + +using __gnu_test::test_container; +using __gnu_test::random_access_iterator_wrapper; +using __gnu_test::copy_tracker; +using __gnu_test::copy_constructor; +using __gnu_test::assignment_operator; +using __gnu_test::destructor; + +typedef test_container<copy_tracker, random_access_iterator_wrapper> Container; + +const int A[] = {10, 20, 1, 11, 2, 21, 28, 29, 12, 35, 15, 27, 6, 16, 7, + 25, 17, 8, 23, 18, 9, 19, 24, 30, 13, 4, 14, 22, 26}; + +void +test_mem1(int throw_count) +{ + bool test __attribute__((unused)) = true; + + copy_tracker vals[30]; + for(int i = 0; i < 30; ++i) + vals[i] = A[i]; + + Container con(vals, vals + 30); + copy_tracker::reset(); + copy_constructor::throw_on(throw_count); + int throw_occurred = 0; + try + { + std::stable_sort(con.begin(), con.end()); + } + catch(...) + { + throw_occurred = 1; + } + + // If a throw occurred in copy_constructor, we will end up with one more + // copy_construct than destructor. + VERIFY( destructor::count() == copy_constructor::count() - throw_occurred ); +} + +bool +is_ordered(const copy_tracker& lhs, const copy_tracker& rhs) +{ return lhs < rhs; } + +void +test_mem2(int throw_count) +{ + bool test __attribute__((unused)) = true; + + copy_tracker vals[30]; + for(int i = 0; i < 30; ++i) + vals[i] = A[i]; + + Container con(vals, vals + 30); + copy_tracker::reset(); + copy_constructor::throw_on(throw_count); + int throw_occurred = 0; + try + { + std::stable_sort(con.begin(), con.end(), is_ordered); + } + catch(...) + { + throw_occurred = 1; + } + + // If a throw occurred in copy_constructor, we will end up with one more + // copy_construct than destructor. + VERIFY( destructor::count() == copy_constructor::count() - throw_occurred ); +} + +int main() +{ + for(int i = 0; i < 60; ++i) + { + test_mem1(i); + test_mem2(i); + } + + return 0; +} diff --git a/libstdc++-v3/testsuite/util/testsuite_hooks.h b/libstdc++-v3/testsuite/util/testsuite_hooks.h index 88155fa..d28a986 100644 --- a/libstdc++-v3/testsuite/util/testsuite_hooks.h +++ b/libstdc++-v3/testsuite/util/testsuite_hooks.h @@ -301,6 +301,10 @@ namespace __gnu_test operator==(const copy_tracker& lhs, const copy_tracker& rhs) { return lhs.id() == rhs.id(); } + inline bool + operator<(const copy_tracker& lhs, const copy_tracker& rhs) + { return lhs.id() < rhs.id(); } + // Class for checking required type conversions, implicit and // explicit for given library data structures. template<typename _Container> |