summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-05 20:58:35 +0000
committerfdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-05 20:58:35 +0000
commit87caff8fb77dd7d7fea3f82a8a47fc65c6a23467 (patch)
treec92053601141aee3cf579cb24c61bd122f4db77d
parent9cb7855ce5cfe3af083267ad4c895287606f30ba (diff)
downloadgcc-87caff8fb77dd7d7fea3f82a8a47fc65c6a23467.tar.gz
2012-10-05 François Dumont <fdumont@gcc.gnu.org>
* include/ext/throw_allocator.h (__throw_value_base): Add move semantic, not throwing. (__throw_value_limit): Likewise. (__throw_value_random): Likewise. * testsuite/util/exception/safety.h: Add validation of C++11 methods emplace/emplace_front/emplace_back/emplace_hint. * testsuite/util/testsuite_container_traits.h: Signal emplace support on deque, forward_list, list and vector. * testsuite/23_containers/deque/requirements/exception/ propagation_consistent.cc: Remove dg-do run fail. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193184 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libstdc++-v3/ChangeLog13
-rw-r--r--libstdc++-v3/include/ext/throw_allocator.h45
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/requirements/exception/propagation_consistent.cc3
-rw-r--r--libstdc++-v3/testsuite/util/exception/safety.h239
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_container_traits.h14
5 files changed, 277 insertions, 37 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 749648a2e30..cf5980750e1 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,16 @@
+2012-10-05 François Dumont <fdumont@gcc.gnu.org>
+
+ * include/ext/throw_allocator.h (__throw_value_base): Add move
+ semantic, not throwing.
+ (__throw_value_limit): Likewise.
+ (__throw_value_random): Likewise.
+ * testsuite/util/exception/safety.h: Add validation of C++11
+ methods emplace/emplace_front/emplace_back/emplace_hint.
+ * testsuite/util/testsuite_container_traits.h: Signal emplace
+ support on deque, forward_list, list and vector.
+ * testsuite/23_containers/deque/requirements/exception/
+ propagation_consistent.cc: Remove dg-do run fail.
+
2012-11-05 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/55215
diff --git a/libstdc++-v3/include/ext/throw_allocator.h b/libstdc++-v3/include/ext/throw_allocator.h
index 4988f8a8a15..8942232c825 100644
--- a/libstdc++-v3/include/ext/throw_allocator.h
+++ b/libstdc++-v3/include/ext/throw_allocator.h
@@ -1,7 +1,6 @@
// -*- C++ -*-
-// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
-// Free Software Foundation, Inc.
+// Copyright (C) 2005-2012 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
@@ -467,6 +466,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
throw_value_base(const throw_value_base& __v) : _M_i(__v._M_i)
{ throw_conditionally(); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ // Shall not throw.
+ throw_value_base(throw_value_base&&) = default;
+#endif
+
explicit throw_value_base(const std::size_t __i) : _M_i(__i)
{ throw_conditionally(); }
#endif
@@ -479,6 +483,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ // Shall not throw.
+ throw_value_base&
+ operator=(throw_value_base&&) = default;
+#endif
+
throw_value_base&
operator++()
{
@@ -568,8 +578,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
throw_value_limit(const throw_value_limit& __other)
: base_type(__other._M_i) { }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ throw_value_limit(throw_value_limit&&) = default;
+#endif
+
explicit throw_value_limit(const std::size_t __i) : base_type(__i) { }
#endif
+
+ throw_value_limit&
+ operator=(const throw_value_limit& __other)
+ {
+ base_type::operator=(__other);
+ return *this;
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ throw_value_limit&
+ operator=(throw_value_limit&&) = default;
+#endif
};
/// Type throwing via random condition.
@@ -583,9 +609,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
throw_value_random(const throw_value_random& __other)
: base_type(__other._M_i) { }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ throw_value_random(throw_value_random&&) = default;
+#endif
explicit throw_value_random(const std::size_t __i) : base_type(__i) { }
#endif
+
+ throw_value_random&
+ operator=(const throw_value_random& __other)
+ {
+ base_type::operator=(__other);
+ return *this;
+ }
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ throw_value_random&
+ operator=(throw_value_random&&) = default;
+#endif
};
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/exception/propagation_consistent.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/exception/propagation_consistent.cc
index 14892344e9f..320084c926b 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/exception/propagation_consistent.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/exception/propagation_consistent.cc
@@ -1,10 +1,9 @@
// { dg-options "-std=gnu++0x" }
// { dg-require-cstdint "" }
-// { dg-do run { xfail *-*-* } }
// 2009-09-09 Benjamin Kosnik <benjamin@redhat.com>
-// Copyright (C) 2009 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 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
diff --git a/libstdc++-v3/testsuite/util/exception/safety.h b/libstdc++-v3/testsuite/util/exception/safety.h
index 50418983ca6..12f41c140fa 100644
--- a/libstdc++-v3/testsuite/util/exception/safety.h
+++ b/libstdc++-v3/testsuite/util/exception/safety.h
@@ -1,6 +1,6 @@
// -*- C++ -*-
-// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 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
@@ -226,17 +226,22 @@ namespace __gnu_test
// compared to the control container.
// NB: Should be equivalent to __test != __control, but
// computed without equivalence operators
- const size_type szt = std::distance(__test.begin(), __test.end());
- const size_type szc = std::distance(__control.begin(),
- __control.end());
- bool __equal_size = szt == szc;
+ const size_type szt
+ = std::distance(__test.begin(), __test.end());
+ const size_type szc
+ = std::distance(__control.begin(), __control.end());
+
+ if (szt != szc)
+ throw std::logic_error(
+ "setup_base::compare containers size not equal");
// Should test iterator validity before and after exception.
bool __equal_it = std::equal(__test.begin(), __test.end(),
__control.begin());
- if (!__equal_size || !__equal_it)
- throw std::logic_error("setup_base::compare containers not equal");
+ if (!__equal_it)
+ throw std::logic_error(
+ "setup_base::compare containers iterators not equal");
return true;
}
@@ -627,6 +632,96 @@ namespace __gnu_test
operator()(_Tp&, _Tp&) { }
};
+ template<typename _Tp, bool = traits<_Tp>::has_push_pop::value
+ && traits<_Tp>::has_emplace::value>
+ struct emplace_front
+ {
+ typedef _Tp container_type;
+ typedef typename container_type::value_type value_type;
+
+ void
+ operator()(_Tp& __test)
+ {
+ try
+ {
+ const value_type cv = generate_unique<value_type>();
+ __test.emplace_front(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>();
+ __test.emplace_front(cv);
+ }
+ catch(const __gnu_cxx::forced_error&)
+ { throw; }
+ }
+ };
+
+ // Specialization, empty.
+ template<typename _Tp>
+ struct emplace_front<_Tp, false>
+ {
+ void
+ operator()(_Tp&) { }
+
+ void
+ operator()(_Tp&, _Tp&) { }
+ };
+
+
+ template<typename _Tp, bool = traits<_Tp>::has_push_pop::value
+ && traits<_Tp>::has_emplace::value
+ && traits<_Tp>::is_reversible::value>
+ struct emplace_back
+ {
+ typedef _Tp container_type;
+ typedef typename container_type::value_type value_type;
+
+ void
+ operator()(_Tp& __test)
+ {
+ try
+ {
+ const value_type cv = generate_unique<value_type>();
+ __test.emplace_back(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>();
+ __test.push_back(cv);
+ }
+ catch(const __gnu_cxx::forced_error&)
+ { throw; }
+ }
+ };
+
+ // Specialization, empty.
+ template<typename _Tp>
+ struct emplace_back<_Tp, false>
+ {
+ void
+ operator()(_Tp&) { }
+
+ void
+ operator()(_Tp&, _Tp&) { }
+ };
+
// Abstract the insert function into two parts:
// 1, insert_base_functions == holds function pointer
@@ -726,9 +821,8 @@ namespace __gnu_test
insert_base() : _F_insert_point(&container_type::insert_after) { }
};
- template<typename _Tp,
- bool = traits<_Tp>::has_insert::value,
- bool = traits<_Tp>::has_insert_after::value>
+ template<typename _Tp, bool = traits<_Tp>::has_insert::value,
+ bool = traits<_Tp>::has_insert_after::value>
struct insert_point;
// Specialization for most containers.
@@ -826,11 +920,12 @@ namespace __gnu_test
operator()(_Tp&, _Tp&) { }
};
- template<typename _Tp,
- bool = traits<_Tp>::has_emplace::value>
+ template<typename _Tp, bool = traits<_Tp>::has_emplace::value
+ && (traits<_Tp>::is_associative::value
+ || traits<_Tp>::is_unordered::value)>
struct emplace;
- // Specialization for most containers.
+ // Specialization for associative and unordered containers.
template<typename _Tp>
struct emplace<_Tp, true>
{
@@ -875,13 +970,56 @@ namespace __gnu_test
operator()(_Tp&, _Tp&) { }
};
- template<typename _Tp,
- bool = traits<_Tp>::has_emplace::value>
- struct emplace_hint;
+ template<typename _Tp, bool = traits<_Tp>::has_emplace::value,
+ bool = traits<_Tp>::is_associative::value
+ || traits<_Tp>::is_unordered::value,
+ bool = traits<_Tp>::has_insert_after::value>
+ struct emplace_point;
// Specialization for most containers.
template<typename _Tp>
- struct emplace_hint<_Tp, true>
+ struct emplace_point<_Tp, true, false, false>
+ {
+ typedef _Tp container_type;
+ typedef typename container_type::value_type value_type;
+
+ 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.begin();
+ std::advance(i, s);
+ __test.emplace(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.begin();
+ std::advance(i, s);
+ __test.emplace(i, cv);
+ }
+ catch(const __gnu_cxx::forced_error&)
+ { throw; }
+ }
+ };
+
+ // Specialization for associative and unordered containers.
+ template<typename _Tp>
+ struct emplace_point<_Tp, true, true, false>
{
typedef _Tp container_type;
typedef typename container_type::value_type value_type;
@@ -920,9 +1058,52 @@ namespace __gnu_test
}
};
- // Specialization, empty.
+ // Specialization for forward_list.
template<typename _Tp>
- struct emplace_hint<_Tp, false>
+ struct emplace_point<_Tp, true, false, true>
+ {
+ typedef _Tp container_type;
+ typedef typename container_type::value_type value_type;
+
+ 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.emplace_after(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.emplace_after(i, cv);
+ }
+ catch(const __gnu_cxx::forced_error&)
+ { throw; }
+ }
+ };
+
+ // Specialization, empty.
+ template<typename _Tp, bool is_associative_or_unordered,
+ bool has_insert_after>
+ struct emplace_point<_Tp, false, is_associative_or_unordered,
+ has_insert_after>
{
void
operator()(_Tp&) { }
@@ -1128,7 +1309,9 @@ namespace __gnu_test
typedef erase_range<container_type> erase_range;
typedef insert_point<container_type> insert_point;
typedef emplace<container_type> emplace;
- typedef emplace_hint<container_type> emplace_hint;
+ typedef emplace_point<container_type> emplace_point;
+ typedef emplace_front<container_type> emplace_front;
+ typedef emplace_back<container_type> emplace_back;
typedef pop_front<container_type> pop_front;
typedef pop_back<container_type> pop_back;
typedef push_front<container_type> push_front;
@@ -1146,7 +1329,9 @@ namespace __gnu_test
erase_range _M_eraser;
insert_point _M_insertp;
emplace _M_emplace;
- emplace_hint _M_emplaceh;
+ emplace_point _M_emplacep;
+ emplace_front _M_emplacef;
+ emplace_back _M_emplaceb;
pop_front _M_popf;
pop_back _M_popb;
push_front _M_pushf;
@@ -1207,7 +1392,9 @@ namespace __gnu_test
_M_functions.push_back(function_type(base_type::_M_eraser));
_M_functions.push_back(function_type(base_type::_M_insertp));
_M_functions.push_back(function_type(base_type::_M_emplace));
- _M_functions.push_back(function_type(base_type::_M_emplaceh));
+ _M_functions.push_back(function_type(base_type::_M_emplacep));
+ _M_functions.push_back(function_type(base_type::_M_emplacef));
+ _M_functions.push_back(function_type(base_type::_M_emplaceb));
_M_functions.push_back(function_type(base_type::_M_popf));
_M_functions.push_back(function_type(base_type::_M_popb));
_M_functions.push_back(function_type(base_type::_M_pushf));
@@ -1328,7 +1515,8 @@ namespace __gnu_test
// Test strong exception guarantee.
// Run through all member functions with a roll-back, consistent
// coherent requirement.
- // all: member functions insert of a single element, push_back, push_front
+ // all: member functions insert and emplace of a single element, push_back,
+ // push_front
// unordered: rehash
template<typename _Tp>
struct propagation_consistent : public test_base<_Tp>
@@ -1360,9 +1548,12 @@ namespace __gnu_test
// Construct containers.
populate p(_M_container_control);
- sync();
// Construct list of member functions to exercise.
+ _M_functions.push_back(function_type(base_type::_M_emplace));
+ _M_functions.push_back(function_type(base_type::_M_emplacep));
+ _M_functions.push_back(function_type(base_type::_M_emplacef));
+ _M_functions.push_back(function_type(base_type::_M_emplaceb));
_M_functions.push_back(function_type(base_type::_M_pushf));
_M_functions.push_back(function_type(base_type::_M_pushb));
_M_functions.push_back(function_type(base_type::_M_insertp));
diff --git a/libstdc++-v3/testsuite/util/testsuite_container_traits.h b/libstdc++-v3/testsuite/util/testsuite_container_traits.h
index 5d8aae04fe0..2e253b96a21 100644
--- a/libstdc++-v3/testsuite/util/testsuite_container_traits.h
+++ b/libstdc++-v3/testsuite/util/testsuite_container_traits.h
@@ -1,6 +1,6 @@
// -*- C++ -*-
-// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 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
@@ -73,6 +73,7 @@ namespace __gnu_test
typedef std::true_type has_insert;
typedef std::true_type has_push_pop;
typedef std::true_type has_size_type_constructor;
+ typedef std::true_type has_emplace;
};
template<typename _Tp1, typename _Tp2>
@@ -85,6 +86,7 @@ namespace __gnu_test
typedef std::true_type has_insert_after;
typedef std::true_type has_push_pop;
typedef std::true_type has_size_type_constructor;
+ typedef std::true_type has_emplace;
};
template<typename _Tp1, typename _Tp2>
@@ -98,6 +100,7 @@ namespace __gnu_test
typedef std::true_type has_insert;
typedef std::true_type has_push_pop;
typedef std::true_type has_size_type_constructor;
+ typedef std::true_type has_emplace;
};
template<typename _Tp1, typename _Tp2>
@@ -111,6 +114,7 @@ namespace __gnu_test
typedef std::true_type has_throwing_erase;
typedef std::true_type has_insert;
typedef std::true_type has_size_type_constructor;
+ typedef std::true_type has_emplace;
};
template<typename _Tp1, typename _Tp2, typename _Tp3>
@@ -148,9 +152,7 @@ namespace __gnu_test
typedef std::true_type has_erase;
typedef std::true_type has_insert;
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
typedef std::true_type has_emplace;
-#endif
};
template<typename _Tp1, typename _Tp2, typename _Tp3, typename _Tp4>
@@ -164,9 +166,7 @@ namespace __gnu_test
typedef std::true_type has_erase;
typedef std::true_type has_insert;
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
typedef std::true_type has_emplace;
-#endif
};
template<typename _Tp1, typename _Tp2, typename _Tp3>
@@ -179,9 +179,7 @@ namespace __gnu_test
typedef std::true_type has_erase;
typedef std::true_type has_insert;
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
typedef std::true_type has_emplace;
-#endif
};
template<typename _Tp1, typename _Tp2, typename _Tp3>
@@ -194,9 +192,7 @@ namespace __gnu_test
typedef std::true_type has_erase;
typedef std::true_type has_insert;
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
typedef std::true_type has_emplace;
-#endif
};
template<typename _Tp1, typename _Tp2>