diff options
author | fdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-05 20:58:35 +0000 |
---|---|---|
committer | fdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-05 20:58:35 +0000 |
commit | 87caff8fb77dd7d7fea3f82a8a47fc65c6a23467 (patch) | |
tree | c92053601141aee3cf579cb24c61bd122f4db77d | |
parent | 9cb7855ce5cfe3af083267ad4c895287606f30ba (diff) | |
download | gcc-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
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> |