# include <unordered_map>
#include <profile/base.h>
+#include <profile/unordered_base.h>
#define _GLIBCXX_BASE unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
#define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
{
/// Class std::unordered_map wrapper with performance instrumentation.
template<typename _Key, typename _Tp,
- typename _Hash = std::hash<_Key>,
+ typename _Hash = std::hash<_Key>,
typename _Pred = std::equal_to<_Key>,
- typename _Alloc = std::allocator<_Key> >
+ typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
class unordered_map
- : public _GLIBCXX_STD_BASE
+ : public _GLIBCXX_STD_BASE,
+ public _Unordered_profile<unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>,
+ true>
{
typedef typename _GLIBCXX_STD_BASE _Base;
+ _Base&
+ _M_base() noexcept { return *this; }
+
+ const _Base&
+ _M_base() const noexcept { return *this; }
+
public:
typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher;
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
- : _Base(__n, __hf, __eql, __a)
- {
- __profcxx_hashtable_construct(this, _Base::bucket_count());
- __profcxx_hashtable_construct2(this);
- }
+ : _Base(__n, __hf, __eql, __a)
+ { }
template<typename _InputIterator>
unordered_map(_InputIterator __f, _InputIterator __l,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
- : _Base(__f, __l, __n, __hf, __eql, __a)
- {
- __profcxx_hashtable_construct(this, _Base::bucket_count());
- __profcxx_hashtable_construct2(this);
- }
+ : _Base(__f, __l, __n, __hf, __eql, __a)
+ { }
- unordered_map(const unordered_map& __x)
- : _Base(__x)
- {
- __profcxx_hashtable_construct(this, _Base::bucket_count());
- __profcxx_hashtable_construct2(this);
- }
+ unordered_map(const unordered_map&) = default;
unordered_map(const _Base& __x)
- : _Base(__x)
- {
- __profcxx_hashtable_construct(this, _Base::bucket_count());
- __profcxx_hashtable_construct2(this);
- }
+ : _Base(__x)
+ { }
- unordered_map(unordered_map&& __x)
- : _Base(std::move(__x))
- {
- __profcxx_hashtable_construct(this, _Base::bucket_count());
- __profcxx_hashtable_construct2(this);
- }
+ unordered_map(unordered_map&&) = default;
unordered_map(initializer_list<value_type> __l,
size_type __n = 0,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
- : _Base(__l, __n, __hf, __eql, __a) { }
+ : _Base(__l, __n, __hf, __eql, __a)
+ { }
unordered_map&
- operator=(const unordered_map& __x)
- {
- *static_cast<_Base*>(this) = __x;
- return *this;
- }
+ operator=(const unordered_map&) = default;
unordered_map&
- operator=(unordered_map&& __x)
- {
- // NB: DR 1204.
- // NB: DR 675.
- this->clear();
- this->swap(__x);
- return *this;
- }
+ operator=(unordered_map&&) = default;
unordered_map&
operator=(initializer_list<value_type> __l)
{
- this->clear();
- this->insert(__l);
+ _M_base() = __l;
return *this;
}
- ~unordered_map() noexcept
- {
- __profcxx_hashtable_destruct(this, _Base::bucket_count(),
- _Base::size());
- _M_profile_destruct();
- }
-
- _Base&
- _M_base() noexcept { return *this; }
-
- const _Base&
- _M_base() const noexcept { return *this; }
-
void
clear() noexcept
{
__profcxx_hashtable_destruct(this, _Base::bucket_count(),
_Base::size());
- _M_profile_destruct();
- _Base::clear();
+ this->_M_profile_destruct();
+ _Base::clear();
}
template<typename... _Args>
_M_profile_resize(__old_size);
}
- void
- insert(const value_type* __first, const value_type* __last)
- {
- size_type __old_size = _Base::bucket_count();
- _Base::insert(__first, __last);
- _M_profile_resize(__old_size);
- }
-
// operator[]
mapped_type&
operator[](const _Key& __k)
void
swap(unordered_map& __x)
- { _Base::swap(__x); }
+ { _Base::swap(__x._M_base()); }
void rehash(size_type __n)
{
if (__old_size != __new_size)
__profcxx_hashtable_resize(this, __old_size, __new_size);
}
-
- void
- _M_profile_destruct()
- {
- size_type __hops = 0, __lc = 0, __chain = 0;
- iterator __it = this->begin();
- while (__it != this->end())
- {
- size_type __bkt = this->bucket(__it->first);
- auto __lit = this->begin(__bkt);
- auto __lend = this->end(__bkt);
- for (++__it, ++__lit; __lit != __lend; ++__it, ++__lit)
- ++__chain;
- if (__chain)
- {
- ++__chain;
- __lc = __lc > __chain ? __lc : __chain;
- __hops += __chain * (__chain - 1) / 2;
- __chain = 0;
- }
- }
- __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
- }
};
template<typename _Key, typename _Tp, typename _Hash,
/// Class std::unordered_multimap wrapper with performance instrumentation.
template<typename _Key, typename _Tp,
- typename _Hash = std::hash<_Key>,
+ typename _Hash = std::hash<_Key>,
typename _Pred = std::equal_to<_Key>,
- typename _Alloc = std::allocator<_Key> >
+ typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
class unordered_multimap
- : public _GLIBCXX_STD_BASE
+ : public _GLIBCXX_STD_BASE,
+ public _Unordered_profile<unordered_multimap<_Key, _Tp,
+ _Hash, _Pred, _Alloc>,
+ false>
{
typedef typename _GLIBCXX_STD_BASE _Base;
+ _Base&
+ _M_base() noexcept { return *this; }
+
+ const _Base&
+ _M_base() const noexcept { return *this; }
+
public:
typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher;
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
- : _Base(__n, __hf, __eql, __a)
- {
- __profcxx_hashtable_construct(this, _Base::bucket_count());
- }
+ : _Base(__n, __hf, __eql, __a)
+ { }
+
template<typename _InputIterator>
unordered_multimap(_InputIterator __f, _InputIterator __l,
size_type __n = 0,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
- : _Base(__f, __l, __n, __hf, __eql, __a)
- {
- __profcxx_hashtable_construct(this, _Base::bucket_count());
- }
+ : _Base(__f, __l, __n, __hf, __eql, __a)
+ { }
- unordered_multimap(const unordered_multimap& __x)
- : _Base(__x)
- {
- __profcxx_hashtable_construct(this, _Base::bucket_count());
- }
+ unordered_multimap(const unordered_multimap&) = default;
unordered_multimap(const _Base& __x)
- : _Base(__x)
- {
- __profcxx_hashtable_construct(this, _Base::bucket_count());
- }
+ : _Base(__x)
+ { }
- unordered_multimap(unordered_multimap&& __x)
- : _Base(std::move(__x))
- {
- __profcxx_hashtable_construct(this, _Base::bucket_count());
- }
+ unordered_multimap(unordered_multimap&&) = default;
unordered_multimap(initializer_list<value_type> __l,
size_type __n = 0,
const hasher& __hf = hasher(),
const key_equal& __eql = key_equal(),
const allocator_type& __a = allocator_type())
- : _Base(__l, __n, __hf, __eql, __a) { }
+ : _Base(__l, __n, __hf, __eql, __a)
+ { }
unordered_multimap&
- operator=(const unordered_multimap& __x)
- {
- *static_cast<_Base*>(this) = __x;
- return *this;
- }
+ operator=(const unordered_multimap&) = default;
unordered_multimap&
- operator=(unordered_multimap&& __x)
- {
- // NB: DR 1204.
- // NB: DR 675.
- this->clear();
- this->swap(__x);
- return *this;
- }
+ operator=(unordered_multimap&&) = default;
unordered_multimap&
operator=(initializer_list<value_type> __l)
{
- this->clear();
- this->insert(__l);
+ _M_base() = __l;
return *this;
}
- ~unordered_multimap() noexcept
- {
- __profcxx_hashtable_destruct(this, _Base::bucket_count(),
- _Base::size());
- _M_profile_destruct();
- }
-
void
clear() noexcept
{
- __profcxx_hashtable_destruct(this, _Base::bucket_count(),
+ __profcxx_hashtable_destruct(this, _Base::bucket_count(),
_Base::size());
- _M_profile_destruct();
- _Base::clear();
+ this->_M_profile_destruct();
+ _Base::clear();
}
template<typename... _Args>
_M_profile_resize(__old_size);
}
- void
- insert(const value_type* __first, const value_type* __last)
- {
- size_type __old_size = _Base::bucket_count();
- _Base::insert(__first, __last);
- _M_profile_resize(__old_size);
- }
-
void
swap(unordered_multimap& __x)
- { _Base::swap(__x); }
+ { _Base::swap(__x._M_base()); }
- void rehash(size_type __n)
+ void
+ rehash(size_type __n)
{
size_type __old_size = _Base::bucket_count();
_Base::rehash(__n);
if (__old_size != __new_size)
__profcxx_hashtable_resize(this, __old_size, __new_size);
}
-
- void
- _M_profile_destruct()
- {
- size_type __hops = 0, __lc = 0, __chain = 0;
- iterator __it = this->begin();
- while (__it != this->end())
- {
- size_type __bkt = this->bucket(__it->first);
- auto __lit = this->begin(__bkt);
- auto __lend = this->end(__bkt);
- for (++__it, ++__lit; __lit != __lend; ++__it, ++__lit)
- ++__chain;
- if (__chain)
- {
- ++__chain;
- __lc = __lc > __chain ? __lc : __chain;
- __hops += __chain * (__chain - 1) / 2;
- __chain = 0;
- }
- }
- __profcxx_hashtable_destruct2(this, __lc, _Base::size(), __hops);
- }
};
template<typename _Key, typename _Tp, typename _Hash,