From b8b4301eecf88d5f727f729a479b8020afe60fdc Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 29 Sep 2010 11:56:34 +0000 Subject: [multiple changes] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2010-09-29 Paolo Carlini * include/Makefile.am: Add debug/forward_list. * include/Makefile.in: Regenerate. * testsuite/util/testsuite_container_traits.h (traits_base): Add has_erase_after and hash_insert_after typedefs. (traits>): Adjust. * testsuite/util/exception/safety.h (erase_point, erase_range, insert_point): Deal correctly with forward_list. * include/Makefile.am: Add. 2010-09-29 François Dumont * src/debug.cc: Add forward_list specific debug messages. * include/debug/forward_list: New. * include/debug/formatter.h: Add debug message ids and before begin iterator state. * include/debug/macros.h (__glibcxx_check_insert_after, __glibcxx_check_insert_range_after, __glibcxx_check_erase_after, __glibcxx_check_erase_range_after): Add. * include/debug/safe_iterator.h (_BeforeBeginHelper): Add. (_Safe_iterator<>::_M_before_dereferenceable, _Safe_iterator<>::_M_is_before_begin): Add. (_Safe_iterator<>::_M_dereferenceable, _Safe_iterator<>::_M_is_end, _Safe_iterator<>::_M_incrementable): Adjust. * include/std/forward_list: Include debug/forward when _GLIBCXX_DEBUG defined. * include/bits/forward_list.h, forward_list.tcc: Put in std::__norm when debug mode is active. * testsuite/23_containers/forward_list/capacity/1.cc: Fix to compile even in debug mode. * testsuite/23_containers/forward_list/debug/erase_after1.cc, erase_after2.cc, erase_after3.cc, erase_after4.cc, erase_after5.cc, insert_after1.cc,erase_after6.cc, erase_after7.cc, insert_after2.cc, erase_after8.cc, insert_after3.cc, erase_after9.cc: New. From-SVN: r164717 --- libstdc++-v3/testsuite/util/exception/safety.h | 134 +++++++++++++++++++++++-- 1 file changed, 125 insertions(+), 9 deletions(-) (limited to 'libstdc++-v3/testsuite/util/exception') diff --git a/libstdc++-v3/testsuite/util/exception/safety.h b/libstdc++-v3/testsuite/util/exception/safety.h index bc96505..202352d 100644 --- a/libstdc++-v3/testsuite/util/exception/safety.h +++ b/libstdc++-v3/testsuite/util/exception/safety.h @@ -347,8 +347,14 @@ namespace __gnu_test _F_erase_range(&container_type::erase) { } }; - template::has_erase::value> - struct erase_point : public erase_base<_Tp> + template::has_erase::value, + bool = traits<_Tp>::has_erase_after::value> + struct erase_point; + + // Specialization for most containers. + template + struct erase_point<_Tp, true, false> : public erase_base<_Tp> { using erase_base<_Tp>::_F_erase_point; @@ -374,17 +380,51 @@ namespace __gnu_test } }; + // Specialization for forward_list. + template + struct erase_point<_Tp, false, true> : public erase_base<_Tp> + { + using erase_base<_Tp>::_F_erase_point; + + void + operator()(_Tp& __container) + { + try + { + // NB: Should be equivalent to size() member function, but + // computed with begin() and end(). + const size_type sz = std::distance(__container.begin(), + __container.end()); + + // NB: Lowest common denominator: use forward iterator operations. + auto i = __container.before_begin(); + std::advance(i, generate(sz)); + + // Makes it easier to think of this as __container.erase(i) + (__container.*_F_erase_point)(i); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + }; + // Specialization, empty. template - struct erase_point<_Tp, false> + struct erase_point<_Tp, false, false> { void operator()(_Tp&) { } }; - template::has_erase::value> - struct erase_range : public erase_base<_Tp> + template::has_erase::value, + bool = traits<_Tp>::has_erase_after::value> + struct erase_range; + + // Specialization for most containers. + template + struct erase_range<_Tp, true, false> : public erase_base<_Tp> { using erase_base<_Tp>::_F_erase_range; @@ -410,9 +450,37 @@ namespace __gnu_test } }; + // Specialization for forward_list. + template + struct erase_range<_Tp, false, true> : public erase_base<_Tp> + { + using erase_base<_Tp>::_F_erase_range; + + void + operator()(_Tp& __container) + { + try + { + const size_type sz = std::distance(__container.begin(), + __container.end()); + size_type s1 = generate(sz); + size_type s2 = generate(sz); + auto i1 = __container.before_begin(); + auto i2 = __container.before_begin(); + std::advance(i1, std::min(s1, s2)); + std::advance(i2, std::max(s1, s2)); + + // Makes it easier to think of this as __container.erase(i1, i2). + (__container.*_F_erase_range)(i1, i2); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + }; + // Specialization, empty. template - struct erase_range<_Tp, false> + struct erase_range<_Tp, false, false> { void operator()(_Tp&) { } @@ -677,8 +745,14 @@ namespace __gnu_test insert_base() : _F_insert_point(&container_type::insert) { } }; - template::has_insert::value> - struct insert_point : public insert_base<_Tp> + template::has_insert::value, + bool = traits<_Tp>::has_insert_after::value> + struct insert_point; + + // Specialization for most containers. + template + struct insert_point<_Tp, true, false> : public insert_base<_Tp> { typedef _Tp container_type; typedef typename container_type::value_type value_type; @@ -718,9 +792,51 @@ namespace __gnu_test } }; + // Specialization for forward_list. + template + struct insert_point<_Tp, false, true> : public insert_base<_Tp> + { + typedef _Tp container_type; + typedef typename container_type::value_type value_type; + using insert_base<_Tp>::_F_insert_point; + + void + operator()(_Tp& __test) + { + try + { + const value_type cv = generate_unique(); + const size_type sz = std::distance(__test.begin(), __test.end()); + size_type s = generate(sz); + auto i = __test.before_begin(); + std::advance(i, s); + (__test.*_F_insert_point)(i, cv); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + + // Assumes containers start out equivalent. + void + operator()(_Tp& __control, _Tp& __test) + { + try + { + const value_type cv = generate_unique(); + const size_type sz = std::distance(__test.begin(), __test.end()); + size_type s = generate(sz); + auto i = __test.before_begin(); + std::advance(i, s); + (__test.*_F_insert_point)(i, cv); + } + catch(const __gnu_cxx::forced_error&) + { throw; } + } + }; + // Specialization, empty. template - struct insert_point<_Tp, false> + struct insert_point<_Tp, false, false> { void operator()(_Tp&) { } -- cgit v1.1