28 #ifndef _GLIBCXX_PROFILE_UNORDERED 29 #define _GLIBCXX_PROFILE_UNORDERED 1 31 namespace std _GLIBCXX_VISIBILITY(default)
35 template<
typename _UnorderedCont,
36 typename _Value,
bool _Cache_hash_code>
37 struct _Bucket_index_helper;
39 template<
typename _UnorderedCont,
typename _Value>
40 struct _Bucket_index_helper<_UnorderedCont, _Value, true>
43 bucket(
const _UnorderedCont& __uc,
44 const __detail::_Hash_node<_Value, true>* __node)
45 {
return __node->_M_hash_code % __uc.bucket_count(); }
48 template<
typename _UnorderedCont,
typename _Value>
49 struct _Bucket_index_helper<_UnorderedCont, _Value, false>
52 bucket(
const _UnorderedCont& __uc,
53 const __detail::_Hash_node<_Value, false>* __node)
54 {
return __uc.bucket(__node->_M_v()); }
57 template<
typename _UnorderedCont,
typename _Key,
typename _Mapped>
58 struct _Bucket_index_helper<_UnorderedCont,
59 std::pair<const _Key, _Mapped>, false>
64 bucket(
const _UnorderedCont& __uc,
65 const __detail::_Hash_node<_Value, false>* __node)
66 {
return __uc.bucket(__node->_M_v().first); }
69 template<
typename _UnorderedCont,
typename _Value,
bool _Cache_hash_code>
71 __get_bucket_index(
const _UnorderedCont& __uc,
72 const __detail::_Hash_node<_Value, _Cache_hash_code>* __node)
74 using __bucket_index_helper
75 = _Bucket_index_helper<_UnorderedCont, _Value, _Cache_hash_code>;
76 return __bucket_index_helper::bucket(__uc, __node);
79 template<
typename _UnorderedCont,
80 typename _Value,
bool _Cache_hash_code>
83 template<
typename _UnorderedCont,
typename _Value>
84 struct _Equal_helper<_UnorderedCont, _Value, true>
87 are_equal(
const _UnorderedCont& __uc,
88 const __detail::_Hash_node<_Value, true>* __lhs,
89 const __detail::_Hash_node<_Value, true>* __rhs)
91 return __lhs->_M_hash_code == __rhs->_M_hash_code
92 && __uc.key_eq()(__lhs->_M_v(), __rhs->_M_v());
96 template<
typename _UnorderedCont,
98 struct _Equal_helper<_UnorderedCont, _Value, false>
101 are_equal(
const _UnorderedCont& __uc,
102 const __detail::_Hash_node<_Value, false>* __lhs,
103 const __detail::_Hash_node<_Value, false>* __rhs)
104 {
return __uc.key_eq()(__lhs->_M_v(), __rhs->_M_v()); }
107 template<
typename _UnorderedCont,
108 typename _Key,
typename _Mapped>
109 struct _Equal_helper<_UnorderedCont,
std::pair<const _Key, _Mapped>, true>
114 are_equal(
const _UnorderedCont& __uc,
115 const __detail::_Hash_node<_Value, true>* __lhs,
116 const __detail::_Hash_node<_Value, true>* __rhs)
118 return __lhs->_M_hash_code == __rhs->_M_hash_code
119 && __uc.key_eq()(__lhs->_M_v().first, __rhs->_M_v().first);
123 template<
typename _UnorderedCont,
124 typename _Key,
typename _Mapped>
125 struct _Equal_helper<_UnorderedCont,
std::pair<const _Key, _Mapped>, false>
130 are_equal(
const _UnorderedCont& __uc,
131 const __detail::_Hash_node<_Value, false>* __lhs,
132 const __detail::_Hash_node<_Value, false>* __rhs)
133 {
return __uc.key_eq()(__lhs->_M_v().first, __rhs->_M_v().first); }
136 template<
typename _UnorderedCont,
typename _Value,
bool _Cache_hash_code>
138 __are_equal(
const _UnorderedCont& __uc,
139 const __detail::_Hash_node<_Value, _Cache_hash_code>* __lhs,
140 const __detail::_Hash_node<_Value, _Cache_hash_code>* __rhs)
143 = _Equal_helper<_UnorderedCont, _Value, _Cache_hash_code>;
144 return __equal_helper::are_equal(__uc, __lhs, __rhs);
147 template<
typename _UnorderedCont,
bool _Unique_keys>
148 class _Unordered_profile
152 {
return *(
static_cast<_UnorderedCont*
>(
this)); }
157 _Unordered_profile() noexcept
158 { _M_profile_construct(); }
160 _Unordered_profile(
const _Unordered_profile&) noexcept
161 : _Unordered_profile() { }
163 _Unordered_profile(_Unordered_profile&& __other) noexcept
164 : _Unordered_profile()
165 { _M_swap(__other); }
167 ~_Unordered_profile()
168 { _M_profile_destruct(); }
171 operator=(
const _Unordered_profile&) noexcept
174 _M_profile_destruct();
175 _M_profile_construct();
179 operator=(_Unordered_profile&& __other) noexcept
185 __other._M_profile_destruct();
186 __other._M_profile_construct();
190 _M_profile_construct() noexcept
192 auto& __uc = _M_conjure();
193 _M_size_info = __profcxx_hashtable_size_construct(__uc.bucket_count());
194 _M_hashfunc_info = __profcxx_hash_func_construct();
198 _M_profile_destruct() noexcept
200 auto& __uc = _M_conjure();
201 __profcxx_hashtable_size_destruct(_M_size_info,
202 __uc.bucket_count(), __uc.size());
205 if (!_M_hashfunc_info)
208 _M_profile_destruct(__unique_keys());
209 _M_hashfunc_info = 0;
213 _M_swap(_Unordered_profile& __other) noexcept
215 std::swap(_M_size_info, __other._M_size_info);
216 std::swap(_M_hashfunc_info, __other._M_hashfunc_info);
220 _M_profile_resize(std::size_t __old_size)
222 auto __new_size = _M_conjure().bucket_count();
223 if (__old_size != __new_size)
224 __profcxx_hashtable_size_resize(_M_size_info, __old_size, __new_size);
238 template<
typename _UnorderedCont,
bool _Unique_keys>
240 _Unordered_profile<_UnorderedCont, _Unique_keys>::
243 auto& __uc = _M_conjure();
244 std::size_t __hops = 0, __lc = 0, __chain = 0;
245 auto __it = __uc.begin();
246 while (__it != __uc.end())
248 auto __bkt = __get_bucket_index(__uc, __it._M_cur);
249 auto __lit = __uc.begin(__bkt);
250 auto __lend = __uc.end(__bkt);
251 for (++__it, ++__lit; __lit != __lend; ++__it, ++__lit)
257 __lc = __lc > __chain ? __lc : __chain;
258 __hops += __chain * (__chain - 1) / 2;
263 __profcxx_hash_func_destruct(_M_hashfunc_info,
264 __lc, __uc.size(), __hops);
267 template<
typename _UnorderedCont,
bool _Unique_keys>
269 _Unordered_profile<_UnorderedCont, _Unique_keys>::
272 auto& __uc = _M_conjure();
273 std::size_t __hops = 0, __lc = 0, __chain = 0, __unique_size = 0;
274 auto __it = __uc.begin();
275 while (__it != __uc.end())
277 auto __bkt = __get_bucket_index(__uc, __it._M_cur);
278 auto __lit = __uc.begin(__bkt);
279 auto __lend = __uc.end(__bkt);
282 for (++__it, ++__lit; __lit != __lend; ++__it, ++__lit)
284 if (!__are_equal(__uc, __pit._M_cur, __it._M_cur))
295 __lc = __lc > __chain ? __lc : __chain;
296 __hops += __chain * (__chain - 1) / 2;
301 __profcxx_hash_func_destruct(_M_hashfunc_info,
302 __lc, __unique_size, __hops);
A container size instrumentation line in the object table.
ISO C++ entities toplevel namespace is std.
A hash performance instrumentation line in the object table.
Struct holding two objects of arbitrary type.