diff options
author | Benjamin Kosnik <bkoz@gcc.gnu.org> | 2009-12-16 05:16:46 +0000 |
---|---|---|
committer | Benjamin Kosnik <bkoz@gcc.gnu.org> | 2009-12-16 05:16:46 +0000 |
commit | 861de21eb294a9d1d2602d4239edfc4a5239a9c9 (patch) | |
tree | f1aa6ebcc1aeff3911a0c56d9fdaffa8e4cc3963 | |
parent | c7d9f803bb64218c45b7e85a9a1e0e143c025205 (diff) | |
download | gcc-861de21eb294a9d1d2602d4239edfc4a5239a9c9.zip gcc-861de21eb294a9d1d2602d4239edfc4a5239a9c9.tar.gz gcc-861de21eb294a9d1d2602d4239edfc4a5239a9c9.tar.bz2 |
PR libstdc++/21772 part 1
2009-12-15 Benjamin Kosnik <bkoz@redhat.com>
PR libstdc++/21772 part 1
* include/ext/throw_allocator.h: Rework.
(__gnu_cxx::throw_allocator): To...
(__gnu_cxx::throw_allocator_limit): ...this.
(__gnu_cxx::throw_allocator_random): ...and this.
(throw_value_base, throw_value_limit, throw_value_random): Add.
(condition_base, random_condition, limit_condition): Add.
(forced_exception_error): To...
(forced_error): ...this.
* testsuite/ext/throw_value: New.
* testsuite/ext/throw_value/cons.cc: New.
* testsuite/ext/throw_allocator/deallocate_global.cc: Adjust for
throw_allocator, forced_exception_error changes.
* testsuite/ext/throw_allocator/check_delete.cc: Same.
* testsuite/ext/throw_allocator/check_allocate_max_size.cc: Same.
* testsuite/ext/throw_allocator/check_deallocate_null.cc: Same.
* testsuite/ext/throw_allocator/explicit_instantiation.cc: Same.
* testsuite/ext/throw_allocator/check_new.cc: Same.
* testsuite/ext/throw_allocator/variadic_construct.cc: Same.
* testsuite/ext/throw_allocator/deallocate_local.cc: Same.
* testsuite/23_containers/list/modifiers/insert/25288.cc: Same.
* testsuite/23_containers/list/modifiers/insert/25288.h: Same.
* testsuite/util/regression/common_type.hpp: Same.
* testsuite/util/regression/rand/priority_queue/
container_rand_regression_test.tcc: Same.
* testsuite/util/regression/rand/assoc/
container_rand_regression_test.h: Same.
* testsuite/util/regression/rand/assoc/
container_rand_regression_test.tcc: Same.
* testsuite/util/regression/basic_type.hpp: Same.
* testsuite/ext/forced_exception_error/cons_virtual_derivation.cc: To...
* testsuite/ext/forced_error/cons_virtual_derivation.cc: ...this, same.
From-SVN: r155283
19 files changed, 534 insertions, 157 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 9efa407..21a6978 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,39 @@ +2009-12-15 Benjamin Kosnik <bkoz@redhat.com> + + PR libstdc++/21772 part 1 + * include/ext/throw_allocator.h: Rework. + (__gnu_cxx::throw_allocator): To... + (__gnu_cxx::throw_allocator_limit): ...this. + (__gnu_cxx::throw_allocator_random): ...and this. + (throw_value_base, throw_value_limit, throw_value_random): Add. + (condition_base, random_condition, limit_condition): Add. + (forced_exception_error): To... + (forced_error): ...this. + * testsuite/ext/throw_value: New. + * testsuite/ext/throw_value/cons.cc: New. + * testsuite/ext/throw_allocator/deallocate_global.cc: Adjust for + throw_allocator, forced_exception_error changes. + * testsuite/ext/throw_allocator/check_delete.cc: Same. + * testsuite/ext/throw_allocator/check_allocate_max_size.cc: Same. + * testsuite/ext/throw_allocator/check_deallocate_null.cc: Same. + * testsuite/ext/throw_allocator/explicit_instantiation.cc: Same. + * testsuite/ext/throw_allocator/check_new.cc: Same. + * testsuite/ext/throw_allocator/variadic_construct.cc: Same. + * testsuite/ext/throw_allocator/deallocate_local.cc: Same. + * testsuite/23_containers/list/modifiers/insert/25288.cc: Same. + * testsuite/23_containers/list/modifiers/insert/25288.h: Same. + * testsuite/util/regression/common_type.hpp: Same. + * testsuite/util/regression/rand/priority_queue/ + container_rand_regression_test.tcc: Same. + * testsuite/util/regression/rand/assoc/ + container_rand_regression_test.h: Same. + * testsuite/util/regression/rand/assoc/ + container_rand_regression_test.tcc: Same. + * testsuite/util/regression/basic_type.hpp: Same. + + * testsuite/ext/forced_exception_error/cons_virtual_derivation.cc: To... + * testsuite/ext/forced_error/cons_virtual_derivation.cc: ...this, same. + 2009-12-15 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/42381 @@ -165,7 +201,7 @@ 2009-12-10 Paolo Carlini <paolo.carlini@oracle.com> Revert: - 2009-12-03 Paolo Carlini <paolo.carlini@oracle.com> + 2009-12-03 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/42261 * include/bits/basic_string.h (_S_construct_aux(_Integer, _Integer, @@ -295,21 +331,21 @@ 2009-11-30 Jonathan Wakely <jwakely.gcc@gmail.com> - * include/tr1_impl/functional (function): Add rvalue support and - tweak doxygen markup. - * testsuite/20_util/function/assign/move.cc: New. - * testsuite/20_util/function/cons/move.cc: New. - * testsuite/20_util/function/invoke/move_only.cc: New. - * testsuite/20_util/function/cmp/cmp_neg.cc: New. - * testsuite/20_util/function/1.cc: Copy from testsuite/tr1/. - * testsuite/20_util/function/2.cc: Likewise. - * testsuite/20_util/function/3.cc: Likewise. - * testsuite/20_util/function/4.cc: Likewise. - * testsuite/20_util/function/5.cc: Likewise. - * testsuite/20_util/function/6.cc: Likewise. - * testsuite/20_util/function/7.cc: Likewise. - * testsuite/20_util/function/8.cc: Likewise. - * testsuite/20_util/function/9.cc: Likewise. + * include/tr1_impl/functional (function): Add rvalue support and + tweak doxygen markup. + * testsuite/20_util/function/assign/move.cc: New. + * testsuite/20_util/function/cons/move.cc: New. + * testsuite/20_util/function/invoke/move_only.cc: New. + * testsuite/20_util/function/cmp/cmp_neg.cc: New. + * testsuite/20_util/function/1.cc: Copy from testsuite/tr1/. + * testsuite/20_util/function/2.cc: Likewise. + * testsuite/20_util/function/3.cc: Likewise. + * testsuite/20_util/function/4.cc: Likewise. + * testsuite/20_util/function/5.cc: Likewise. + * testsuite/20_util/function/6.cc: Likewise. + * testsuite/20_util/function/7.cc: Likewise. + * testsuite/20_util/function/8.cc: Likewise. + * testsuite/20_util/function/9.cc: Likewise. 2009-11-29 Jonathan Wakely <jwakely.gcc@gmail.com> @@ -374,10 +410,10 @@ 2009-11-19 Johannes Singler <singler@kit.edu> - * include/parallel/partition.h (__parallel_partition): Correctly - initialize chunk size. - (__parallel_nth_element): Respect nth_element_minimal_n. Use - sequential nth_element as base case, instead of sequential sort. + * include/parallel/partition.h (__parallel_partition): Correctly + initialize chunk size. + (__parallel_nth_element): Respect nth_element_minimal_n. Use + sequential nth_element as base case, instead of sequential sort. 2009-11-17 Benjamin Kosnik <bkoz@redhat.com> @@ -848,26 +884,26 @@ 009-10-20 Paolo Carlini <paolo.carlini@oracle.com> - PR libstdc++/41773 - Revert: - 2009-10-20 Paolo Carlini <paolo.carlini@oracle.com> - - * include/bits/basic_string.h (_S_construct(const _CharT*, size_type, - const _Alloc&)): New, declare. - (_S_construct(_CharT*, _CharT*, const _Alloc&), - _S_construct(const _CharT*, const _CharT*, const _Alloc&), - _S_construct(iterator, iterator, const _Alloc&), - _S_construct(const_iterator, const_iterator, const _Alloc&)): New, - forward to the latter. - * include/bits/basic_string.tcc (_S_construct(const _CharT*, - size_type, const _Alloc&)): Define. - (basic_string(const basic_string&, size_type, size_type), - basic_string(const basic_string&, size_type, size_type, - const _Alloc&), basic_string(const _CharT*, size_type, - const _Alloc&), basic_string(const _CharT*, const _Alloc&), - basic_string(initializer_list<>, const _Alloc&)): Call the latter. - * config/abi/pre/gnu.ver: Remove recently added exports. - * src/string-inst.cc: Remove instantiations. + PR libstdc++/41773 + Revert: + 2009-10-20 Paolo Carlini <paolo.carlini@oracle.com> + + * include/bits/basic_string.h (_S_construct(const _CharT*, size_type, + const _Alloc&)): New, declare. + (_S_construct(_CharT*, _CharT*, const _Alloc&), + _S_construct(const _CharT*, const _CharT*, const _Alloc&), + _S_construct(iterator, iterator, const _Alloc&), + _S_construct(const_iterator, const_iterator, const _Alloc&)): New, + forward to the latter. + * include/bits/basic_string.tcc (_S_construct(const _CharT*, + size_type, const _Alloc&)): Define. + (basic_string(const basic_string&, size_type, size_type), + basic_string(const basic_string&, size_type, size_type, + const _Alloc&), basic_string(const _CharT*, size_type, + const _Alloc&), basic_string(const _CharT*, const _Alloc&), + basic_string(initializer_list<>, const _Alloc&)): Call the latter. + * config/abi/pre/gnu.ver: Remove recently added exports. + * src/string-inst.cc: Remove instantiations. 2009-10-20 Paolo Carlini <paolo.carlini@oracle.com> diff --git a/libstdc++-v3/include/ext/throw_allocator.h b/libstdc++-v3/include/ext/throw_allocator.h index 69daa15..fd939b2 100644 --- a/libstdc++-v3/include/ext/throw_allocator.h +++ b/libstdc++-v3/include/ext/throw_allocator.h @@ -36,9 +36,11 @@ /** @file ext/throw_allocator.h * This file is a GNU extension to the Standard C++ Library. * - * Contains an exception-throwing allocator, useful for testing - * exception safety. In addition, allocation addresses are stored and - * sanity checked. + * Contains two exception-generating types (throw_value, throw_allocator) + * intended to be used as value and allocator types while testing + * exception safety in templatized containers and algorithms. The + * allocator has additional log and debug features. The exception + * generated is of type forced_exception_error. */ #ifndef _THROW_ALLOCATOR_H @@ -64,27 +66,30 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) /** - * @brief Thown by throw_allocator. + * @brief Thown by exception safety machinery. * @ingroup exceptions */ - struct forced_exception_error : public std::exception + struct forced_error : public std::exception { }; - // Substitute for concurrence_error object in the case of -fno-exceptions. + // Substitute for forced_error object when -fno-exceptions. inline void - __throw_forced_exception_error() + __throw_forced_error() { #if __EXCEPTIONS - throw forced_exception_error(); + throw forced_error(); #else __builtin_abort(); #endif } - // Base class for checking address and label information about - // allocations. Create a std::map between the allocated address - // (void*) and a datum for annotations, which are a pair of numbers - // corresponding to label and allocated size. + + /** + * @brief Base class for checking address and label information + * about allocations. Create a std::map between the allocated + * address (void*) and a datum for annotations, which are a pair of + * numbers corresponding to label and allocated size. + */ struct annotate_base { annotate_base() @@ -92,7 +97,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) label(); map(); } - + static void set_label(size_t l) { label() = l; } @@ -106,7 +111,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) { if (p == NULL) { - std::string error("throw_allocator_base::insert null insert!\n"); + std::string error("annotate_base::insert null insert!\n"); log_to_string(error, make_entry(p, size)); std::__throw_logic_error(error.c_str()); } @@ -114,7 +119,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) const_iterator found = map().find(p); if (found != map().end()) { - std::string error("throw_allocator_base::insert double insert!\n"); + std::string error("annotate_base::insert double insert!\n"); log_to_string(error, make_entry(p, size)); log_to_string(error, *found); std::__throw_logic_error(error.c_str()); @@ -130,7 +135,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) map().erase(p); } - // See if a particular address and size has been allocated. + // See if a particular address and allocation size has been saved. inline void check_allocated(void* p, size_t size) { @@ -142,7 +147,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) log_to_string(error, make_entry(p, size)); std::__throw_logic_error(error.c_str()); } - + if (found->second.second != size) { std::string error("annotate_base::check_allocated by value " @@ -166,7 +171,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) log_to_string(found, *beg); ++beg; } - + if (!found.empty()) { std::string error("annotate_base::check_allocated by label\n"); @@ -213,15 +218,15 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) static size_t& label() { - static size_t ll; - return ll; + static size_t _S_label(std::numeric_limits<size_t>::max()); + return _S_label; } static map_type& map() { - static map_type mp; - return mp; + static map_type _S_map; + return _S_map; } }; @@ -237,47 +242,133 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) return os << error; } - /// Base class for probability control and throw. - struct probability_base + + /** + * @brief Base struct for condition policy. + * + * Requires a public member function with the signature + * void throw_conditionally() + */ + struct condition_base + { + virtual ~condition_base() { }; + }; + + + /** + * @brief Base class for incremental control and throw. + */ + struct limit_condition : public condition_base { - // Scope-level probability adjustor objects: set probability for - // throw at the beginning of a scope block, and restores to - // previous probability when object is destroyed on exiting the - // block. + // Scope-level adjustor objects: set limit for throw at the + // beginning of a scope block, and restores to previous limit when + // object is destroyed on exiting the block. struct adjustor_base { private: - const double _M_prob; + const size_t _M_orig; public: - adjustor_base() : _M_prob(get_probability()) { } + adjustor_base() : _M_orig(limit()) { } + + virtual + ~adjustor_base() { set_limit(_M_orig); } + }; + + /// Never enter the condition. + struct never_adjustor : public adjustor_base + { + never_adjustor() { set_limit(std::numeric_limits<size_t>::max()); } + }; + + /// Always enter the condition. + struct always_adjustor : public adjustor_base + { + always_adjustor() { set_limit(count()); } + }; + + /// Enter the nth condition. + struct limit_adjustor : public adjustor_base + { + limit_adjustor(const size_t __l) { set_limit(__l); } + }; + + // Increment _S_count every time called. + // If _S_count matches the limit count, throw. + static void + throw_conditionally() + { + if (count() == limit()) + __throw_forced_error(); + ++count(); + } + + static size_t& + count() + { + static size_t _S_count(0); + return _S_count; + } + + static size_t& + limit() + { + static size_t _S_limit(std::numeric_limits<size_t>::max()); + return _S_limit; + } + + // Zero the throw counter, set limit to argument. + static void + set_limit(const size_t __l) + { + limit() = __l; + count() = 0; + } + }; + + + /** + * @brief Base class for random probability control and throw. + */ + struct random_condition : public condition_base + { + // Scope-level adjustor objects: set probability for throw at the + // beginning of a scope block, and restores to previous + // probability when object is destroyed on exiting the block. + struct adjustor_base + { + private: + const double _M_orig; + + public: + adjustor_base() : _M_orig(probability()) { } virtual ~adjustor_base() - { set_probability(_M_prob); } + { set_probability(_M_orig); } }; - // Group condition. + /// Group condition. struct group_adjustor : public adjustor_base { group_adjustor(size_t size) - { set_probability(1 - std::pow(double(1 - get_probability()), + { set_probability(1 - std::pow(double(1 - probability()), double(0.5 / (size + 1)))); } }; - // Never enter the condition. + /// Never enter the condition. struct never_adjustor : public adjustor_base { never_adjustor() { set_probability(0); } }; - // Always enter the condition. + /// Always enter the condition. struct always_adjustor : public adjustor_base { always_adjustor() { set_probability(1); } }; - probability_base() + random_condition() { probability(); engine(); @@ -287,15 +378,11 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) set_probability(double __p) { probability() = __p; } - static double& - get_probability() - { return probability(); } - - void + static void throw_conditionally() { - if (generate() < get_probability()) - __throw_forced_exception_error(); + if (generate() < probability()) + __throw_forced_error(); } void @@ -311,7 +398,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) typedef std::tr1::mt19937 engine_type; #endif - double + static double generate() { #ifdef __GXX_EXPERIMENTAL_CXX0X__ @@ -327,7 +414,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) double random = generator(); if (random < distribution.min() || random > distribution.max()) { - std::string __s("throw_allocator::throw_conditionally"); + std::string __s("random_condition::generate"); __s += "\n"; __s += "random number generated is: "; char buf[40]; @@ -342,54 +429,186 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) static double& probability() { - static double __p; - return __p; + static double _S_p; + return _S_p; } static engine_type& engine() { - static engine_type __e; - return __e; + static engine_type _S_e; + return _S_e; } }; + /** - * @brief Allocator class with logging and exception control. + * @brief Class with exception generation control. Intended to be + * used as a value_type in templatized code. + * + * Note: Destructor not allowed to throw. + */ + template<typename _Cond> + struct throw_value_base : public _Cond + { + typedef _Cond condition_type; + + using condition_type::throw_conditionally; + + std::size_t _M_i; + + throw_value_base() : _M_i(0) + { throw_conditionally(); } + + throw_value_base(const throw_value_base& __v) + : _M_i(__v._M_i) + { throw_conditionally(); } + + explicit throw_value_base(const std::size_t __i) + : _M_i(__i) + { throw_conditionally(); } + + throw_value_base& + operator=(const throw_value_base& __v) + { + throw_conditionally(); + _M_i = __v._M_i; + return *this; + } + + throw_value_base& + operator++() + { + throw_conditionally(); + ++_M_i; + return *this; + } + }; + + template<typename _Cond> + inline void + swap(throw_value_base<_Cond>& __a, throw_value_base<_Cond>& __b) + { + typedef throw_value_base<_Cond> throw_value; + throw_value::throw_conditionally(); + throw_value orig(__a); + __a = __b; + __b = orig; + } + + // General instantiable types requirements. + template<typename _Cond> + inline bool + operator==(const throw_value_base<_Cond>& __a, + const throw_value_base<_Cond>& __b) + { + typedef throw_value_base<_Cond> throw_value; + throw_value::throw_conditionally(); + bool __ret = __a._M_i == __b._M_i; + return __ret; + } + + template<typename _Cond> + inline bool + operator<(const throw_value_base<_Cond>& __a, + const throw_value_base<_Cond>& __b) + { + typedef throw_value_base<_Cond> throw_value; + throw_value::throw_conditionally(); + bool __ret = __a._M_i < __b._M_i; + return __ret; + } + + // Numeric algorithms instantiable types requirements. + template<typename _Cond> + inline throw_value_base<_Cond> + operator+(const throw_value_base<_Cond>& __a, + const throw_value_base<_Cond>& __b) + { + typedef throw_value_base<_Cond> throw_value; + throw_value::throw_conditionally(); + throw_value __ret(__a._M_i + __b._M_i); + return __ret; + } + + template<typename _Cond> + inline throw_value_base<_Cond> + operator-(const throw_value_base<_Cond>& __a, + const throw_value_base<_Cond>& __b) + { + typedef throw_value_base<_Cond> throw_value; + throw_value::throw_conditionally(); + throw_value __ret(__a._M_i - __b._M_i); + return __ret; + } + + template<typename _Cond> + inline throw_value_base<_Cond> + operator*(const throw_value_base<_Cond>& __a, + const throw_value_base<_Cond>& __b) + { + typedef throw_value_base<_Cond> throw_value; + throw_value::throw_conditionally(); + throw_value __ret(__a._M_i * __b._M_i); + return __ret; + } + + /// Type throwing via limit condition. + struct throw_value_limit : public throw_value_base<limit_condition> + { + typedef throw_value_base<limit_condition> base_type; + + throw_value_limit() { } + + throw_value_limit(const throw_value_limit& __other) + : base_type(__other._M_i) { } + + explicit throw_value_limit(const std::size_t __i) : base_type(__i) { } + }; + + /// Type throwing via random condition. + struct throw_value_random : public throw_value_base<random_condition> + { + typedef throw_value_base<random_condition> base_type; + + throw_value_random() { } + + throw_value_random(const throw_value_random& __other) + : base_type(__other._M_i) { } + + + explicit throw_value_random(const std::size_t __i) : base_type(__i) { } + }; + + + /** + * @brief Allocator class with logging and exception generation control. + * Intended to be used as an allocator_type in templatized code. * @ingroup allocators + * + * Note: Deallocate not allowed to throw. */ - template<typename T> - class throw_allocator - : public probability_base, public annotate_base + template<typename _Tp, typename _Cond> + class throw_allocator_base + : public annotate_base, public _Cond { public: typedef size_t size_type; typedef ptrdiff_t difference_type; - typedef T value_type; + typedef _Tp value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; private: - std::allocator<value_type> _M_allocator; + typedef _Cond condition_type; - public: - template<typename U> - struct rebind - { - typedef throw_allocator<U> other; - }; - - throw_allocator() throw() { } - - throw_allocator(const throw_allocator&) throw() { } - - template<typename U> - throw_allocator(const throw_allocator<U>&) throw() { } + std::allocator<value_type> _M_allocator; - ~throw_allocator() throw() { } + using condition_type::throw_conditionally; + public: size_type max_size() const throw() { return _M_allocator.max_size(); } @@ -407,7 +626,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) } void - construct(pointer __p, const T& val) + construct(pointer __p, const value_type& val) { return _M_allocator.construct(__p, val); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ @@ -435,19 +654,97 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) annotate_base::check_allocated(__p, __t); } - using annotate_base::check_allocated; - }; + void + check_allocated(size_type __n) + { annotate_base::check_allocated(__n); } + }; - template<typename T> + template<typename _Tp, typename _Cond> inline bool - operator==(const throw_allocator<T>&, const throw_allocator<T>&) + operator==(const throw_allocator_base<_Tp, _Cond>&, + const throw_allocator_base<_Tp, _Cond>&) { return true; } - template<typename T> + template<typename _Tp, typename _Cond> inline bool - operator!=(const throw_allocator<T>&, const throw_allocator<T>&) + operator!=(const throw_allocator_base<_Tp, _Cond>&, + const throw_allocator_base<_Tp, _Cond>&) { return false; } + /// Allocator throwing via limit condition. + template<typename _Tp> + struct throw_allocator_limit + : public throw_allocator_base<_Tp, limit_condition> + { + template<typename _Tp1> + struct rebind + { typedef throw_allocator_limit<_Tp1> other; }; + + throw_allocator_limit() throw() { } + + throw_allocator_limit(const throw_allocator_limit&) throw() { } + + template<typename _Tp1> + throw_allocator_limit(const throw_allocator_limit<_Tp1>&) throw() { } + + ~throw_allocator_limit() throw() { } + }; + + /// Allocator throwing via random condition. + template<typename _Tp> + struct throw_allocator_random + : public throw_allocator_base<_Tp, random_condition> + { + template<typename _Tp1> + struct rebind + { typedef throw_allocator_random<_Tp1> other; }; + + throw_allocator_random() throw() { } + + throw_allocator_random(const throw_allocator_random&) throw() { } + + template<typename _Tp1> + throw_allocator_random(const throw_allocator_random<_Tp1>&) throw() { } + + ~throw_allocator_random() throw() { } + }; + _GLIBCXX_END_NAMESPACE +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + +# include <bits/functional_hash.h> + +namespace std +{ + /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit. + template<> + struct hash<__gnu_cxx::throw_value_limit> + : public std::unary_function<__gnu_cxx::throw_value_limit, size_t> + { + size_t + operator()(__gnu_cxx::throw_value_limit __val) const + { + std::hash<std::size_t> h; + size_t __result = h(__val._M_i); + return __result; + } + }; + + /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit. + template<> + struct hash<__gnu_cxx::throw_value_random> + : public std::unary_function<__gnu_cxx::throw_value_random, size_t> + { + size_t + operator()(__gnu_cxx::throw_value_random __val) const + { + std::hash<std::size_t> h; + size_t __result = h(__val._M_i); + return __result; + } + }; +} // end namespace std +#endif + #endif diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.cc index e9195dd..eb286e0 100644 --- a/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.cc +++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.cc @@ -23,7 +23,7 @@ int main() { typedef int value_type; - typedef __gnu_cxx::throw_allocator<value_type> allocator_type; + typedef __gnu_cxx::throw_allocator_random<value_type> allocator_type; typedef std::list<value_type, allocator_type> list_type; insert1<list_type>(); diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.h b/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.h index c3ec662..aebbe0b 100644 --- a/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.h +++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.h @@ -47,7 +47,7 @@ void insert1() list1.insert(list1.begin(), 10, 99); VERIFY( false ); } - catch (__gnu_cxx::forced_exception_error&) + catch (__gnu_cxx::forced_error&) { VERIFY( true ); } @@ -74,7 +74,7 @@ void insert1() list2.insert(list2.begin(), data, data + 10); VERIFY( false ); } - catch (__gnu_cxx::forced_exception_error&) + catch (__gnu_cxx::forced_error&) { VERIFY( true ); } diff --git a/libstdc++-v3/testsuite/ext/forced_exception_error/cons_virtual_derivation.cc b/libstdc++-v3/testsuite/ext/forced_error/cons_virtual_derivation.cc index ba6b1f4..f505a79 100644 --- a/libstdc++-v3/testsuite/ext/forced_exception_error/cons_virtual_derivation.cc +++ b/libstdc++-v3/testsuite/ext/forced_error/cons_virtual_derivation.cc @@ -24,7 +24,7 @@ int main() { - typedef __gnu_cxx::forced_exception_error test_type; + typedef __gnu_cxx::forced_error test_type; __gnu_test::diamond_derivation<test_type, true>::test(); return 0; } diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/check_allocate_max_size.cc b/libstdc++-v3/testsuite/ext/throw_allocator/check_allocate_max_size.cc index 1c7a627..b4d0996 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/check_allocate_max_size.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/check_allocate_max_size.cc @@ -24,7 +24,7 @@ int main() { typedef int value_type; - typedef __gnu_cxx::throw_allocator<value_type> allocator_type; + typedef __gnu_cxx::throw_allocator_random<value_type> allocator_type; __gnu_test::check_allocate_max_size<allocator_type>(); return 0; } diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/check_deallocate_null.cc b/libstdc++-v3/testsuite/ext/throw_allocator/check_deallocate_null.cc index 1a98078..3f9d37a 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/check_deallocate_null.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/check_deallocate_null.cc @@ -24,7 +24,7 @@ int main() { typedef int value_type; - typedef __gnu_cxx::throw_allocator<value_type> allocator_type; + typedef __gnu_cxx::throw_allocator_random<value_type> allocator_type; try { __gnu_test::check_deallocate_null<allocator_type>(); } catch (std::logic_error&) diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/check_delete.cc b/libstdc++-v3/testsuite/ext/throw_allocator/check_delete.cc index cfc38ee..181a1eb 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/check_delete.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/check_delete.cc @@ -24,7 +24,7 @@ int main() { - typedef __gnu_cxx::throw_allocator<unsigned int> allocator_type; + typedef __gnu_cxx::throw_allocator_random<unsigned int> allocator_type; __gnu_test::check_delete<allocator_type, true>(); return 0; } diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/check_new.cc b/libstdc++-v3/testsuite/ext/throw_allocator/check_new.cc index 2d42891..4338471 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/check_new.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/check_new.cc @@ -24,7 +24,7 @@ int main() { - typedef __gnu_cxx::throw_allocator<unsigned int> allocator_type; + typedef __gnu_cxx::throw_allocator_random<unsigned int> allocator_type; __gnu_test::check_new<allocator_type, true>(); return 0; } diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_global.cc b/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_global.cc index c53517e..65ef6db 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_global.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_global.cc @@ -25,7 +25,7 @@ typedef char char_t; typedef std::char_traits<char_t> traits_t; -typedef __gnu_cxx::throw_allocator<char_t> allocator_t; +typedef __gnu_cxx::throw_allocator_random<char_t> allocator_t; typedef std::basic_string<char_t, traits_t, allocator_t> string_t; string_t s("bayou bend"); diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_local.cc b/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_local.cc index c2e918c..4f00928 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_local.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_local.cc @@ -24,7 +24,7 @@ typedef char char_t; typedef std::char_traits<char_t> traits_t; -typedef __gnu_cxx::throw_allocator<char_t> allocator_t; +typedef __gnu_cxx::throw_allocator_random<char_t> allocator_t; typedef std::basic_string<char_t, traits_t, allocator_t> string_t; int main() diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/explicit_instantiation.cc b/libstdc++-v3/testsuite/ext/throw_allocator/explicit_instantiation.cc index 659807d..c260044 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/explicit_instantiation.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/explicit_instantiation.cc @@ -21,4 +21,5 @@ #include <cstdlib> #include <ext/throw_allocator.h> -template class __gnu_cxx::throw_allocator<int>; +template class __gnu_cxx::throw_allocator_random<int>; +template class __gnu_cxx::throw_allocator_limit<int>; diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/variadic_construct.cc b/libstdc++-v3/testsuite/ext/throw_allocator/variadic_construct.cc index 395cacc..fd1ee8d 100644 --- a/libstdc++-v3/testsuite/ext/throw_allocator/variadic_construct.cc +++ b/libstdc++-v3/testsuite/ext/throw_allocator/variadic_construct.cc @@ -29,7 +29,7 @@ void test01() { bool test __attribute__((unused)) = true; typedef std::pair<int, char> pair_type; - __gnu_cxx::throw_allocator<pair_type> alloc1; + __gnu_cxx::throw_allocator_random<pair_type> alloc1; pair_type* ptp1 = alloc1.allocate(1); alloc1.construct(ptp1, 3, 'a'); diff --git a/libstdc++-v3/testsuite/ext/throw_value/cons.cc b/libstdc++-v3/testsuite/ext/throw_value/cons.cc new file mode 100644 index 0000000..fa3f3f7 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/throw_value/cons.cc @@ -0,0 +1,43 @@ +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2009 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 of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <type_traits> +#include <ext/throw_allocator.h> + +void foo1() +{ + typedef __gnu_cxx::throw_value_limit value_type; + value_type v1; + value_type v2(v2); + value_type v3(value_type()); +} + +bool foo2() +{ + typedef __gnu_cxx::throw_value_limit value_type; + bool b = std::is_convertible<value_type, value_type>::value; + return b; +} + +int main() +{ + foo1(); + foo2(); + return 0; +} diff --git a/libstdc++-v3/testsuite/util/regression/basic_type.hpp b/libstdc++-v3/testsuite/util/regression/basic_type.hpp index 6d12bd6..9fe6ef2 100644 --- a/libstdc++-v3/testsuite/util/regression/basic_type.hpp +++ b/libstdc++-v3/testsuite/util/regression/basic_type.hpp @@ -46,7 +46,7 @@ namespace test { #define PB_DS_BASE_C_DEC \ std::basic_string<char, std::char_traits<char>, \ - __gnu_cxx::throw_allocator<char> > + __gnu_cxx::throw_allocator_random<char> > struct basic_type : public PB_DS_BASE_C_DEC { diff --git a/libstdc++-v3/testsuite/util/regression/common_type.hpp b/libstdc++-v3/testsuite/util/regression/common_type.hpp index 9e6a80d..37705bc 100644 --- a/libstdc++-v3/testsuite/util/regression/common_type.hpp +++ b/libstdc++-v3/testsuite/util/regression/common_type.hpp @@ -46,7 +46,7 @@ namespace __gnu_pbds { namespace test { - typedef __gnu_cxx::throw_allocator<basic_type> alloc_type; + typedef __gnu_cxx::throw_allocator_random<basic_type> alloc_type; struct hash { diff --git a/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.h b/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.h index 393463a..ca44332 100644 --- a/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.h +++ b/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.h @@ -80,7 +80,7 @@ namespace detail typedef typename test_traits::native_type native_type; typedef twister_rand_gen gen; typedef __gnu_pbds::container_traits<Cntnr> container_traits; - typedef __gnu_cxx::throw_allocator<char> alloc_t; + typedef __gnu_cxx::throw_allocator_random<char> alloc_t; enum op { diff --git a/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.tcc b/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.tcc index d995a04..43cdb9f 100644 --- a/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.tcc +++ b/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.tcc @@ -66,7 +66,7 @@ default_constructor() { m_p_c = new Cntnr; } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -107,7 +107,7 @@ copy_constructor() p_c = new Cntnr(*m_p_c); std::swap(p_c, m_p_c); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -134,7 +134,7 @@ assignment_operator() * p_c =* m_p_c; std::swap(p_c, m_p_c); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -210,7 +210,7 @@ it_constructor_imp(__gnu_pbds::cc_hash_tag) }; std::swap(p_c, m_p_c); } - catch (__gnu_cxx::forced_exception_error&) + catch (__gnu_cxx::forced_error&) { done = false; } @@ -293,7 +293,7 @@ it_constructor_imp(__gnu_pbds::gp_hash_tag) }; std::swap(p_c, m_p_c); } - catch (__gnu_cxx::forced_exception_error&) + catch (__gnu_cxx::forced_error&) { done = false; } @@ -329,7 +329,7 @@ it_constructor_imp(__gnu_pbds::tree_tag) }; std::swap(p_c, m_p_c); } - catch (__gnu_cxx::forced_exception_error&) + catch (__gnu_cxx::forced_error&) { done = false; } @@ -354,7 +354,7 @@ it_constructor_imp(__gnu_pbds::list_update_tag) p_c = new Cntnr(m_p_c->begin(), m_p_c->end()); std::swap(p_c, m_p_c); } - catch (__gnu_cxx::forced_exception_error&) + catch (__gnu_cxx::forced_error&) { done = false; } @@ -392,7 +392,7 @@ it_constructor_imp(__gnu_pbds::pat_trie_tag) std::swap(p_c, m_p_c); } - catch (__gnu_cxx::forced_exception_error&) + catch (__gnu_cxx::forced_error&) { done = false; } @@ -1088,7 +1088,7 @@ insert() } m_native_c.insert(test_traits::native_value(v)); } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -1139,7 +1139,7 @@ subscript_imp(__gnu_pbds::detail::false_type) m_native_c[test_traits::native_value(v).first] = test_traits::native_value(v).second; } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -1164,7 +1164,7 @@ subscript_imp(__gnu_pbds::detail::true_type) (*m_p_c)[v] = __gnu_pbds::null_mapped_type(); m_native_c.insert(test_traits::native_value(v)); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -1213,7 +1213,7 @@ erase() PB_DS_THROW_IF_FAILED(m_p_c->find(k) == m_p_c->end(), "", m_p_c, &m_native_c); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; @@ -1251,7 +1251,7 @@ erase_if() PB_DS_THROW_IF_FAILED(ersd == native_ersd, ersd << " " << native_ersd, m_p_c, &m_native_c); } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; PB_DS_THROW_IF_FAILED(container_traits::erase_can_throw, @@ -1329,7 +1329,7 @@ erase_it_imp(__gnu_pbds::detail::true_type) if (range_guarantee) PB_DS_THROW_IF_FAILED(next_ers_it == next_it, "", m_p_c, &m_native_c); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; PB_DS_THROW_IF_FAILED(container_traits::erase_can_throw, container_traits::erase_can_throw, m_p_c, &m_native_c); @@ -1392,7 +1392,7 @@ erase_rev_it_imp(__gnu_pbds::detail::true_type) if (native_it != m_native_c.end()) m_native_c.erase(native_it); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; PB_DS_THROW_IF_FAILED(container_traits::erase_can_throw, @@ -1763,7 +1763,7 @@ split_join_imp(__gnu_pbds::detail::true_type) PB_DS_THROW_IF_FAILED(rhs.empty(), rhs.size(), m_p_c, &m_native_c); m_p_c->swap(lhs); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; PB_DS_THROW_IF_FAILED(container_traits::split_join_can_throw, diff --git a/libstdc++-v3/testsuite/util/regression/rand/priority_queue/container_rand_regression_test.tcc b/libstdc++-v3/testsuite/util/regression/rand/priority_queue/container_rand_regression_test.tcc index fe8ae6b..f964911 100644 --- a/libstdc++-v3/testsuite/util/regression/rand/priority_queue/container_rand_regression_test.tcc +++ b/libstdc++-v3/testsuite/util/regression/rand/priority_queue/container_rand_regression_test.tcc @@ -66,7 +66,7 @@ default_constructor() { m_p_c = new Cntnr; } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -110,7 +110,7 @@ copy_constructor() p_c = new Cntnr(*m_p_c); std::swap(p_c, m_p_c); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -139,7 +139,7 @@ assignment_operator() *p_c = *m_p_c; std::swap(p_c, m_p_c); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -180,7 +180,7 @@ it_constructor() std::swap(p_c, m_p_c); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -433,7 +433,7 @@ push() _GLIBCXX_THROW_IF(sz != m_p_c->size() - 1, sz, m_p_c, &m_native_c); m_native_c.push(test_traits::native_value(v)); } - catch(__gnu_cxx::forced_exception_error& ) + catch(__gnu_cxx::forced_error&) { done = false; } @@ -475,7 +475,7 @@ modify() m_native_c.modify(native_v, new_native_v); } } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c); @@ -517,7 +517,7 @@ pop() m_native_c.pop(); } } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c); @@ -560,7 +560,7 @@ erase_if() _GLIBCXX_THROW_IF(ersd != native_ersd, ersd << " " << native_ersd, m_p_c, &m_native_c); } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c); @@ -592,7 +592,7 @@ erase_it() m_p_c->erase(it); } } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c); @@ -715,7 +715,7 @@ split_join() _GLIBCXX_THROW_IF(rhs.size() != 0, rhs.size(), m_p_c, &m_native_c); _GLIBCXX_THROW_IF(!rhs.empty(), rhs.size(), m_p_c, &m_native_c); } - catch(__gnu_cxx::forced_exception_error&) + catch(__gnu_cxx::forced_error&) { done = false; const bool b = __gnu_pbds::container_traits<cntnr>::split_join_can_throw; |