diff options
| author | fdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-04-22 20:22:07 +0000 |
|---|---|---|
| committer | fdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-04-22 20:22:07 +0000 |
| commit | 60eba405d23ddeb2d0a289d2b79bebdd89b7c01b (patch) | |
| tree | 5569c55c22034b5f3fd78df58dc634c6e5709ead /libstdc++-v3/include/ext | |
| parent | 609c541fd0e5e1a46f856ce125e0249352b995f2 (diff) | |
| download | ppe42-gcc-60eba405d23ddeb2d0a289d2b79bebdd89b7c01b.tar.gz ppe42-gcc-60eba405d23ddeb2d0a289d2b79bebdd89b7c01b.zip | |
2013-04-22 François Dumont <fdumont@gcc.gnu.org>
* include/bits/hashtable_policy.h: Add C++11 allocator support.
* include/bits/hashtable.h: Likewise.
* include/bits/unordered_set.h: Likewise.
* include/bits/unordered_map.h: Likewise.
* include/debug/unordered_set: Likewise.
* include/debug/unordered_map: Likewise.
* include/std/unordered_set: Remove bits/algobase.h
include. Replace bits/alloc_traits.h by ext/alloc_traits.h.
* include/std/unordered_map: Likewise.
* include/ext/throw_allocator.h: Add checks on calls to allocator
construct/destroy.
(std::hash<__gnu_cxx::throw_value_limit>): Add conditional throw.
(std::hash<__gnu_cxx::throw_value_random>): Likewise.
* testsuite/util/regression/rand/priority_queue
/container_rand_regression_test.tcc: Adapt.
* testsuite/util/regression/rand/assoc
/container_rand_regression_test.tcc: Likewise.
* testsuite/util/testsuite_counter_type.h: Add count of destructors.
* testsuite/23_containers/unordered_set
/not_default_constructible_hash_neg.cc: Adjust dg-error line number.
* testsuite/23_containers/unordered_set/instantiation_neg.cc: Likewise.
* testsuite/23_containers/unordered_set/allocator/copy.cc: New.
* testsuite/23_containers/unordered_set/allocator/copy_assign.cc: New.
* testsuite/23_containers/unordered_set/allocator/minimal.cc: New.
* testsuite/23_containers/unordered_set/allocator/move_assign.cc: New.
* testsuite/23_containers/unordered_set/allocator/noexcept.cc: New.
* testsuite/23_containers/unordered_set/allocator/swap.cc: New.
* testsuite/23_containers/unordered_multiset/allocator/copy.cc: New.
* testsuite/23_containers/unordered_multiset/allocator/copy_assign.cc:
New.
* testsuite/23_containers/unordered_multiset/allocator/minimal.cc: New.
* testsuite/23_containers/unordered_multiset/allocator/move_assign.cc:
New.
* testsuite/23_containers/unordered_multiset/allocator/noexcept.cc: New.
* testsuite/23_containers/unordered_multiset/allocator/swap.cc: New.
* testsuite/23_containers/unordered_map/allocator/copy.cc: New.
* testsuite/23_containers/unordered_map/allocator/copy_assign.cc: New.
* testsuite/23_containers/unordered_map/allocator/minimal.cc: New.
* testsuite/23_containers/unordered_map/allocator/move_assign.cc: New.
* testsuite/23_containers/unordered_map/allocator/noexcept.cc:
New.
* testsuite/23_containers/unordered_map/allocator/swap.cc: New.
* testsuite/23_containers/unordered_multimap/allocator/copy.cc: New.
* testsuite/23_containers/unordered_multimap/allocator/copy_assign.cc:
New.
* testsuite/23_containers/unordered_multimap/allocator/minimal.cc: New.
* testsuite/23_containers/unordered_multimap/allocator/move_assign.cc:
New.
* testsuite/23_containers/unordered_multimap/allocator/noexcept.cc: New.
* testsuite/23_containers/unordered_multimap/allocator/swap.cc: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@198158 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/ext')
| -rw-r--r-- | libstdc++-v3/include/ext/throw_allocator.h | 226 |
1 files changed, 195 insertions, 31 deletions
diff --git a/libstdc++-v3/include/ext/throw_allocator.h b/libstdc++-v3/include/ext/throw_allocator.h index 7e610ed17fe..31f22dc386a 100644 --- a/libstdc++-v3/include/ext/throw_allocator.h +++ b/libstdc++-v3/include/ext/throw_allocator.h @@ -90,7 +90,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION annotate_base() { label(); - map(); + map_alloc(); } static void @@ -111,8 +111,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::__throw_logic_error(error.c_str()); } - const_iterator found = map().find(p); - if (found != map().end()) + const_iterator found = map_alloc().find(p); + if (found != map_alloc().end()) { std::string error("annotate_base::insert double insert!\n"); log_to_string(error, make_entry(p, size)); @@ -120,22 +120,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::__throw_logic_error(error.c_str()); } - map().insert(make_entry(p, size)); + map_alloc().insert(make_entry(p, size)); } void erase(void* p, size_t size) { check_allocated(p, size); - map().erase(p); + map_alloc().erase(p); } +#if __cplusplus >= 201103L + void + insert_construct(void* p) + { + if (!p) + { + std::string error("annotate_base::insert_construct null!\n"); + std::__throw_logic_error(error.c_str()); + } + + auto found = map_construct().find(p); + if (found != map_construct().end()) + { + std::string error("annotate_base::insert_construct double insert!\n"); + log_to_string(error, std::make_pair(p, get_label())); + log_to_string(error, *found); + std::__throw_logic_error(error.c_str()); + } + + map_construct().insert(std::make_pair(p, get_label())); + } + + void + erase_construct(void* p) + { + check_constructed(p); + map_construct().erase(p); + } +#endif + // See if a particular address and allocation size has been saved. inline void check_allocated(void* p, size_t size) { - const_iterator found = map().find(p); - if (found == map().end()) + const_iterator found = map_alloc().find(p); + if (found == map_alloc().end()) { std::string error("annotate_base::check_allocated by value " "null erase!\n"); @@ -155,32 +185,121 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // See if a given label has been allocated. inline void - check_allocated(size_t label) + check(size_t label) + { + std::string found; + { + const_iterator beg = map_alloc().begin(); + const_iterator end = map_alloc().end(); + while (beg != end) + { + if (beg->second.first == label) + log_to_string(found, *beg); + ++beg; + } + } + +#if __cplusplus >= 201103L + { + auto beg = map_construct().begin(); + auto end = map_construct().end(); + while (beg != end) + { + if (beg->second == label) + log_to_string(found, *beg); + ++beg; + } + } +#endif + + if (!found.empty()) + { + std::string error("annotate_base::check by label\n"); + error += found; + std::__throw_logic_error(error.c_str()); + } + } + + // See if there is anything left allocated or constructed. + inline static void + check() + { + std::string found; + { + const_iterator beg = map_alloc().begin(); + const_iterator end = map_alloc().end(); + while (beg != end) + { + log_to_string(found, *beg); + ++beg; + } + } + +#if __cplusplus >= 201103L + { + auto beg = map_construct().begin(); + auto end = map_construct().end(); + while (beg != end) + { + log_to_string(found, *beg); + ++beg; + } + } +#endif + + if (!found.empty()) + { + std::string error("annotate_base::check \n"); + error += found; + std::__throw_logic_error(error.c_str()); + } + } + +#if __cplusplus >= 201103L + inline void + check_constructed(void* p) + { + auto found = map_construct().find(p); + if (found == map_construct().end()) + { + std::string error("annotate_base::check_constructed not " + "constructed!\n"); + log_to_string(error, std::make_pair(p, get_label())); + std::__throw_logic_error(error.c_str()); + } + } + + inline void + check_constructed(size_t label) { - const_iterator beg = map().begin(); - const_iterator end = map().end(); + auto beg = map_construct().begin(); + auto end = map_construct().end(); std::string found; while (beg != end) { - if (beg->second.first == label) + if (beg->second == label) log_to_string(found, *beg); ++beg; } if (!found.empty()) { - std::string error("annotate_base::check_allocated by label\n"); + std::string error("annotate_base::check_constructed by label\n"); error += found; std::__throw_logic_error(error.c_str()); } } +#endif private: - typedef std::pair<size_t, size_t> data_type; - typedef std::map<void*, data_type> map_type; - typedef map_type::value_type entry_type; - typedef map_type::const_iterator const_iterator; - typedef map_type::const_reference const_reference; + typedef std::pair<size_t, size_t> data_type; + typedef std::map<void*, data_type> map_alloc_type; + typedef map_alloc_type::value_type entry_type; + typedef map_alloc_type::const_iterator const_iterator; + typedef map_alloc_type::const_reference const_reference; +#if __cplusplus >= 201103L + typedef std::map<void*, size_t> map_construct_type; +#endif friend std::ostream& operator<<(std::ostream&, const annotate_base&); @@ -189,8 +308,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION make_entry(void* p, size_t size) { return std::make_pair(p, data_type(get_label(), size)); } - void - log_to_string(std::string& s, const_reference ref) const + static void + log_to_string(std::string& s, const_reference ref) { char buf[40]; const char tab('\t'); @@ -210,6 +329,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION s += '\n'; } +#if __cplusplus >= 201103L + static void + log_to_string(std::string& s, const std::pair<const void*, size_t>& ref) + { + char buf[40]; + const char tab('\t'); + s += "label: "; + unsigned long l = static_cast<unsigned long>(ref.second); + __builtin_sprintf(buf, "%lu", l); + s += buf; + s += tab; + s += "address: "; + __builtin_sprintf(buf, "%p", ref.first); + s += buf; + s += '\n'; + } +#endif + static size_t& label() { @@ -217,12 +354,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return _S_label; } - static map_type& - map() + static map_alloc_type& + map_alloc() { - static map_type _S_map; + static map_alloc_type _S_map; return _S_map; } + +#if __cplusplus >= 201103L + static map_construct_type& + map_construct() + { + static map_construct_type _S_map; + return _S_map; + } +#endif }; inline std::ostream& @@ -230,10 +376,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { std::string error; typedef annotate_base base_type; - base_type::const_iterator beg = __b.map().begin(); - base_type::const_iterator end = __b.map().end(); - for (; beg != end; ++beg) - __b.log_to_string(error, *beg); + { + base_type::const_iterator beg = __b.map_alloc().begin(); + base_type::const_iterator end = __b.map_alloc().end(); + for (; beg != end; ++beg) + __b.log_to_string(error, *beg); + } +#if __cplusplus >= 201103L + { + auto beg = __b.map_construct().begin(); + auto end = __b.map_construct().end(); + for (; beg != end; ++beg) + __b.log_to_string(error, *beg); + } +#endif return os << error; } @@ -685,12 +841,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Up, typename... _Args> void construct(_Up* __p, _Args&&... __args) - { return _M_allocator.construct(__p, std::forward<_Args>(__args)...); } + { + _M_allocator.construct(__p, std::forward<_Args>(__args)...); + insert_construct(__p); + } template<typename _Up> void destroy(_Up* __p) - { _M_allocator.destroy(__p); } + { + erase_construct(__p); + _M_allocator.destroy(__p); + } #else void construct(pointer __p, const value_type& val) @@ -716,8 +878,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } void - check_allocated(size_type __n) - { annotate_base::check_allocated(__n); } + check(size_type __n) + { annotate_base::check(__n); } }; template<typename _Tp, typename _Cond> @@ -791,13 +953,14 @@ namespace std _GLIBCXX_VISIBILITY(default) size_t operator()(const __gnu_cxx::throw_value_limit& __val) const { + __gnu_cxx::throw_value_limit::throw_conditionally(); 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. + /// Explicit specialization of std::hash for __gnu_cxx::throw_value_random. template<> struct hash<__gnu_cxx::throw_value_random> : public std::unary_function<__gnu_cxx::throw_value_random, size_t> @@ -805,6 +968,7 @@ namespace std _GLIBCXX_VISIBILITY(default) size_t operator()(const __gnu_cxx::throw_value_random& __val) const { + __gnu_cxx::throw_value_random::throw_conditionally(); std::hash<std::size_t> __h; size_t __result = __h(__val._M_i); return __result; |

