aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/util/exception
diff options
context:
space:
mode:
authorPaolo Carlini <paolo@gcc.gnu.org>2010-09-29 11:56:34 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2010-09-29 11:56:34 +0000
commitb8b4301eecf88d5f727f729a479b8020afe60fdc (patch)
tree83bdb10f8d357c1745bb3b46f210b83062e71171 /libstdc++-v3/testsuite/util/exception
parent38df2baf3f40af1c1af065993cf86e0254b765df (diff)
downloadgcc-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.h134
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&) { }