summaryrefslogtreecommitdiffstats
path: root/libstdc++-v3/include/ext
diff options
context:
space:
mode:
authorfdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4>2013-04-22 20:22:07 +0000
committerfdumont <fdumont@138bc75d-0d04-0410-961f-82ee72b054a4>2013-04-22 20:22:07 +0000
commit60eba405d23ddeb2d0a289d2b79bebdd89b7c01b (patch)
tree5569c55c22034b5f3fd78df58dc634c6e5709ead /libstdc++-v3/include/ext
parent609c541fd0e5e1a46f856ce125e0249352b995f2 (diff)
downloadppe42-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.h226
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;
OpenPOWER on IntegriCloud