diff options
author | Paolo Carlini <paolo@gcc.gnu.org> | 2010-09-29 11:56:34 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2010-09-29 11:56:34 +0000 |
commit | b8b4301eecf88d5f727f729a479b8020afe60fdc (patch) | |
tree | 83bdb10f8d357c1745bb3b46f210b83062e71171 /libstdc++-v3/testsuite/util/exception | |
parent | 38df2baf3f40af1c1af065993cf86e0254b765df (diff) | |
download | gcc-b8b4301eecf88d5f727f729a479b8020afe60fdc.zip gcc-b8b4301eecf88d5f727f729a479b8020afe60fdc.tar.gz gcc-b8b4301eecf88d5f727f729a479b8020afe60fdc.tar.bz2 |
[multiple changes]
2010-09-29 Paolo Carlini <paolo.carlini@oracle.com>
* 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<forward_list<>>): 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 <francois.cppdevs@free.fr>
* 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
Diffstat (limited to 'libstdc++-v3/testsuite/util/exception')
-rw-r--r-- | libstdc++-v3/testsuite/util/exception/safety.h | 134 |
1 files changed, 125 insertions, 9 deletions
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<typename _Tp, bool = traits<_Tp>::has_erase::value> - struct erase_point : public erase_base<_Tp> + template<typename _Tp, + bool = traits<_Tp>::has_erase::value, + bool = traits<_Tp>::has_erase_after::value> + struct erase_point; + + // Specialization for most containers. + template<typename _Tp> + 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<typename _Tp> + 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<typename _Tp> - struct erase_point<_Tp, false> + struct erase_point<_Tp, false, false> { void operator()(_Tp&) { } }; - template<typename _Tp, bool = traits<_Tp>::has_erase::value> - struct erase_range : public erase_base<_Tp> + template<typename _Tp, + bool = traits<_Tp>::has_erase::value, + bool = traits<_Tp>::has_erase_after::value> + struct erase_range; + + // Specialization for most containers. + template<typename _Tp> + 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<typename _Tp> + 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<typename _Tp> - 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<typename _Tp, bool = traits<_Tp>::has_insert::value> - struct insert_point : public insert_base<_Tp> + template<typename _Tp, + bool = traits<_Tp>::has_insert::value, + bool = traits<_Tp>::has_insert_after::value> + struct insert_point; + + // Specialization for most containers. + template<typename _Tp> + 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<typename _Tp> + 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<value_type>(); + 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<value_type>(); + 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<typename _Tp> - struct insert_point<_Tp, false> + struct insert_point<_Tp, false, false> { void operator()(_Tp&) { } |