Viewing file: unordered_base.h (8.9 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
// Profiling unordered containers implementation details -*- C++ -*-
// Copyright (C) 2013-2018 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.
// Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation.
// 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/>.
/** @file profile/unordered_base.h * This file is a GNU profile extension to the Standard C++ Library. */
#ifndef _GLIBCXX_PROFILE_UNORDERED #define _GLIBCXX_PROFILE_UNORDERED 1
namespace std _GLIBCXX_VISIBILITY(default) { namespace __profile { template<typename _UnorderedCont, typename _Value, bool _Cache_hash_code> struct _Bucket_index_helper;
template<typename _UnorderedCont, typename _Value> struct _Bucket_index_helper<_UnorderedCont, _Value, true> { static std::size_t bucket(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, true>* __node) { return __node->_M_hash_code % __uc.bucket_count(); } };
template<typename _UnorderedCont, typename _Value> struct _Bucket_index_helper<_UnorderedCont, _Value, false> { static std::size_t bucket(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, false>* __node) { return __uc.bucket(__node->_M_v()); } };
template<typename _UnorderedCont, typename _Key, typename _Mapped> struct _Bucket_index_helper<_UnorderedCont, std::pair<const _Key, _Mapped>, false> { typedef std::pair<const _Key, _Mapped> _Value;
static std::size_t bucket(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, false>* __node) { return __uc.bucket(__node->_M_v().first); } };
template<typename _UnorderedCont, typename _Value, bool _Cache_hash_code> std::size_t __get_bucket_index(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, _Cache_hash_code>* __node) { using __bucket_index_helper = _Bucket_index_helper<_UnorderedCont, _Value, _Cache_hash_code>; return __bucket_index_helper::bucket(__uc, __node); }
template<typename _UnorderedCont, typename _Value, bool _Cache_hash_code> struct _Equal_helper;
template<typename _UnorderedCont, typename _Value> struct _Equal_helper<_UnorderedCont, _Value, true> { static std::size_t are_equal(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, true>* __lhs, const __detail::_Hash_node<_Value, true>* __rhs) { return __lhs->_M_hash_code == __rhs->_M_hash_code && __uc.key_eq()(__lhs->_M_v(), __rhs->_M_v()); } };
template<typename _UnorderedCont, typename _Value> struct _Equal_helper<_UnorderedCont, _Value, false> { static std::size_t are_equal(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, false>* __lhs, const __detail::_Hash_node<_Value, false>* __rhs) { return __uc.key_eq()(__lhs->_M_v(), __rhs->_M_v()); } };
template<typename _UnorderedCont, typename _Key, typename _Mapped> struct _Equal_helper<_UnorderedCont, std::pair<const _Key, _Mapped>, true> { typedef std::pair<const _Key, _Mapped> _Value;
static std::size_t are_equal(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, true>* __lhs, const __detail::_Hash_node<_Value, true>* __rhs) { return __lhs->_M_hash_code == __rhs->_M_hash_code && __uc.key_eq()(__lhs->_M_v().first, __rhs->_M_v().first); } };
template<typename _UnorderedCont, typename _Key, typename _Mapped> struct _Equal_helper<_UnorderedCont, std::pair<const _Key, _Mapped>, false> { typedef std::pair<const _Key, _Mapped> _Value;
static std::size_t are_equal(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, false>* __lhs, const __detail::_Hash_node<_Value, false>* __rhs) { return __uc.key_eq()(__lhs->_M_v().first, __rhs->_M_v().first); } };
template<typename _UnorderedCont, typename _Value, bool _Cache_hash_code> bool __are_equal(const _UnorderedCont& __uc, const __detail::_Hash_node<_Value, _Cache_hash_code>* __lhs, const __detail::_Hash_node<_Value, _Cache_hash_code>* __rhs) { using __equal_helper = _Equal_helper<_UnorderedCont, _Value, _Cache_hash_code>; return __equal_helper::are_equal(__uc, __lhs, __rhs); }
template<typename _UnorderedCont, bool _Unique_keys> class _Unordered_profile { _UnorderedCont& _M_conjure() { return *(static_cast<_UnorderedCont*>(this)); }
using __unique_keys = std::integral_constant<bool, _Unique_keys>;
protected: _Unordered_profile() noexcept { _M_profile_construct(); }
_Unordered_profile(const _Unordered_profile&) noexcept : _Unordered_profile() { }
_Unordered_profile(_Unordered_profile&& __other) noexcept : _Unordered_profile() { _M_swap(__other); }
~_Unordered_profile() { _M_profile_destruct(); }
_Unordered_profile& operator=(const _Unordered_profile&) noexcept { // Assignment just reset profiling. _M_profile_destruct(); _M_profile_construct(); }
_Unordered_profile& operator=(_Unordered_profile&& __other) noexcept { // Take profiling of the moved instance... _M_swap(__other);
// ...and then reset other instance profiling. __other._M_profile_destruct(); __other._M_profile_construct(); }
void _M_profile_construct() noexcept { auto& __uc = _M_conjure(); _M_size_info = __profcxx_hashtable_size_construct(__uc.bucket_count()); _M_hashfunc_info = __profcxx_hash_func_construct(); }
void _M_profile_destruct() noexcept { auto& __uc = _M_conjure(); __profcxx_hashtable_size_destruct(_M_size_info, __uc.bucket_count(), __uc.size()); _M_size_info = 0;
if (!_M_hashfunc_info) return;
_M_profile_destruct(__unique_keys()); _M_hashfunc_info = 0; }
void _M_swap(_Unordered_profile& __other) noexcept { std::swap(_M_size_info, __other._M_size_info); std::swap(_M_hashfunc_info, __other._M_hashfunc_info); }
void _M_profile_resize(std::size_t __old_size) { auto __new_size = _M_conjure().bucket_count(); if (__old_size != __new_size) __profcxx_hashtable_size_resize(_M_size_info, __old_size, __new_size); }
__gnu_profile::__container_size_info* _M_size_info; __gnu_profile::__hashfunc_info* _M_hashfunc_info;
private: void _M_profile_destruct(std::true_type);
void _M_profile_destruct(std::false_type); };
template<typename _UnorderedCont, bool _Unique_keys> void _Unordered_profile<_UnorderedCont, _Unique_keys>:: _M_profile_destruct(std::true_type) { auto& __uc = _M_conjure(); std::size_t __hops = 0, __lc = 0, __chain = 0; auto __it = __uc.begin(); while (__it != __uc.end()) { auto __bkt = __get_bucket_index(__uc, __it._M_cur); auto __lit = __uc.begin(__bkt); auto __lend = __uc.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_hash_func_destruct(_M_hashfunc_info, __lc, __uc.size(), __hops); }
template<typename _UnorderedCont, bool _Unique_keys> void _Unordered_profile<_UnorderedCont, _Unique_keys>:: _M_profile_destruct(std::false_type) { auto& __uc = _M_conjure(); std::size_t __hops = 0, __lc = 0, __chain = 0, __unique_size = 0; auto __it = __uc.begin(); while (__it != __uc.end()) { auto __bkt = __get_bucket_index(__uc, __it._M_cur); auto __lit = __uc.begin(__bkt); auto __lend = __uc.end(__bkt); auto __pit = __it; ++__unique_size; for (++__it, ++__lit; __lit != __lend; ++__it, ++__lit) { if (!__are_equal(__uc, __pit._M_cur, __it._M_cur)) { ++__chain; ++__unique_size; __pit = __it; } }
if (__chain) { ++__chain; __lc = __lc > __chain ? __lc : __chain; __hops += __chain * (__chain - 1) / 2; __chain = 0; } }
__profcxx_hash_func_destruct(_M_hashfunc_info, __lc, __unique_size, __hops); }
} // namespace __profile } // namespace std
#endif
|