| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586 |
- // Profiling unordered_map/unordered_multimap implementation -*- C++ -*-
- // Copyright (C) 2009-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_map
- * This file is a GNU profile extension to the Standard C++ Library.
- */
- #ifndef _GLIBCXX_PROFILE_UNORDERED_MAP
- #define _GLIBCXX_PROFILE_UNORDERED_MAP 1
- #if __cplusplus < 201103L
- # include <bits/c++0x_warning.h>
- #else
- # 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
- namespace std _GLIBCXX_VISIBILITY(default)
- {
- namespace __profile
- {
- /// Class std::unordered_map wrapper with performance instrumentation.
- template<typename _Key, typename _Tp,
- typename _Hash = std::hash<_Key>,
- typename _Pred = std::equal_to<_Key>,
- typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
- class unordered_map
- : 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;
- typedef typename _Base::key_equal key_equal;
- typedef typename _Base::allocator_type allocator_type;
- typedef typename _Base::key_type key_type;
- typedef typename _Base::value_type value_type;
- typedef typename _Base::difference_type difference_type;
- typedef typename _Base::reference reference;
- typedef typename _Base::const_reference const_reference;
- typedef typename _Base::mapped_type mapped_type;
- typedef typename _Base::iterator iterator;
- typedef typename _Base::const_iterator const_iterator;
- unordered_map() = default;
- explicit
- unordered_map(size_type __n,
- const hasher& __hf = hasher(),
- const key_equal& __eql = key_equal(),
- const allocator_type& __a = allocator_type())
- : _Base(__n, __hf, __eql, __a) { }
- template<typename _InputIterator>
- unordered_map(_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) { }
- unordered_map(const unordered_map&) = default;
- unordered_map(const _Base& __x)
- : _Base(__x) { }
- unordered_map(unordered_map&&) = default;
- explicit
- unordered_map(const allocator_type& __a)
- : _Base(__a) { }
- unordered_map(const unordered_map& __umap,
- const allocator_type& __a)
- : _Base(__umap, __a) { }
- unordered_map(unordered_map&& __umap,
- const allocator_type& __a)
- : _Base(std::move(__umap._M_base()), __a) { }
- 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) { }
- unordered_map(size_type __n, const allocator_type& __a)
- : unordered_map(__n, hasher(), key_equal(), __a)
- { }
- unordered_map(size_type __n, const hasher& __hf,
- const allocator_type& __a)
- : unordered_map(__n, __hf, key_equal(), __a)
- { }
- template<typename _InputIterator>
- unordered_map(_InputIterator __first, _InputIterator __last,
- size_type __n,
- const allocator_type& __a)
- : unordered_map(__first, __last, __n, hasher(), key_equal(), __a)
- { }
- template<typename _InputIterator>
- unordered_map(_InputIterator __first, _InputIterator __last,
- size_type __n, const hasher& __hf,
- const allocator_type& __a)
- : unordered_map(__first, __last, __n, __hf, key_equal(), __a)
- { }
- unordered_map(initializer_list<value_type> __l,
- size_type __n,
- const allocator_type& __a)
- : unordered_map(__l, __n, hasher(), key_equal(), __a)
- { }
- unordered_map(initializer_list<value_type> __l,
- size_type __n, const hasher& __hf,
- const allocator_type& __a)
- : unordered_map(__l, __n, __hf, key_equal(), __a)
- { }
- unordered_map&
- operator=(const unordered_map&) = default;
- unordered_map&
- operator=(unordered_map&&) = default;
- unordered_map&
- operator=(initializer_list<value_type> __l)
- {
- this->_M_profile_destruct();
- _M_base() = __l;
- this->_M_profile_construct();
- return *this;
- }
- void
- clear() noexcept
- {
- this->_M_profile_destruct();
- _Base::clear();
- this->_M_profile_construct();
- }
- template<typename... _Args>
- std::pair<iterator, bool>
- emplace(_Args&&... __args)
- {
- size_type __old_size = _Base::bucket_count();
- std::pair<iterator, bool> __res
- = _Base::emplace(std::forward<_Args>(__args)...);
- this->_M_profile_resize(__old_size);
- return __res;
- }
- template<typename... _Args>
- iterator
- emplace_hint(const_iterator __it, _Args&&... __args)
- {
- size_type __old_size = _Base::bucket_count();
- iterator __res
- = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
- this->_M_profile_resize(__old_size);
- return __res;
- }
- void
- insert(std::initializer_list<value_type> __l)
- {
- size_type __old_size = _Base::bucket_count();
- _Base::insert(__l);
- this->_M_profile_resize(__old_size);
- }
- std::pair<iterator, bool>
- insert(const value_type& __obj)
- {
- size_type __old_size = _Base::bucket_count();
- std::pair<iterator, bool> __res = _Base::insert(__obj);
- this->_M_profile_resize(__old_size);
- return __res;
- }
- iterator
- insert(const_iterator __iter, const value_type& __v)
- {
- size_type __old_size = _Base::bucket_count();
- iterator __res = _Base::insert(__iter, __v);
- this->_M_profile_resize(__old_size);
- return __res;
- }
- template<typename _Pair, typename = typename
- std::enable_if<std::is_constructible<value_type,
- _Pair&&>::value>::type>
- std::pair<iterator, bool>
- insert(_Pair&& __obj)
- {
- size_type __old_size = _Base::bucket_count();
- std::pair<iterator, bool> __res
- = _Base::insert(std::forward<_Pair>(__obj));
- this->_M_profile_resize(__old_size);
- return __res;
- }
- template<typename _Pair, typename = typename
- std::enable_if<std::is_constructible<value_type,
- _Pair&&>::value>::type>
- iterator
- insert(const_iterator __iter, _Pair&& __v)
- {
- size_type __old_size = _Base::bucket_count();
- iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v));
- this->_M_profile_resize(__old_size);
- return __res;
- }
- template<typename _InputIter>
- void
- insert(_InputIter __first, _InputIter __last)
- {
- size_type __old_size = _Base::bucket_count();
- _Base::insert(__first, __last);
- this->_M_profile_resize(__old_size);
- }
- // operator[]
- mapped_type&
- operator[](const _Key& __k)
- {
- size_type __old_size = _Base::bucket_count();
- mapped_type& __res = _M_base()[__k];
- this->_M_profile_resize(__old_size);
- return __res;
- }
- mapped_type&
- operator[](_Key&& __k)
- {
- size_type __old_size = _Base::bucket_count();
- mapped_type& __res = _M_base()[std::move(__k)];
- this->_M_profile_resize(__old_size);
- return __res;
- }
- void
- swap(unordered_map& __x)
- noexcept( noexcept(__x._M_base().swap(__x)) )
- {
- _Base::swap(__x._M_base());
- this->_M_swap(__x);
- }
- void rehash(size_type __n)
- {
- size_type __old_size = _Base::bucket_count();
- _Base::rehash(__n);
- this->_M_profile_resize(__old_size);
- }
- };
- template<typename _Key, typename _Tp, typename _Hash,
- typename _Pred, typename _Alloc>
- inline void
- swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
- unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
- noexcept(noexcept(__x.swap(__y)))
- { __x.swap(__y); }
- template<typename _Key, typename _Tp, typename _Hash,
- typename _Pred, typename _Alloc>
- inline bool
- operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
- const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
- { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
- template<typename _Key, typename _Tp, typename _Hash,
- typename _Pred, typename _Alloc>
- inline bool
- operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
- const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
- { return !(__x == __y); }
- #undef _GLIBCXX_BASE
- #undef _GLIBCXX_STD_BASE
- #define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>
- #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
- /// Class std::unordered_multimap wrapper with performance instrumentation.
- template<typename _Key, typename _Tp,
- typename _Hash = std::hash<_Key>,
- typename _Pred = std::equal_to<_Key>,
- typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
- class unordered_multimap
- : 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;
- typedef typename _Base::key_equal key_equal;
- typedef typename _Base::allocator_type allocator_type;
- typedef typename _Base::key_type key_type;
- typedef typename _Base::value_type value_type;
- typedef typename _Base::difference_type difference_type;
- typedef typename _Base::reference reference;
- typedef typename _Base::const_reference const_reference;
- typedef typename _Base::iterator iterator;
- typedef typename _Base::const_iterator const_iterator;
- unordered_multimap() = default;
- explicit
- unordered_multimap(size_type __n,
- const hasher& __hf = hasher(),
- const key_equal& __eql = key_equal(),
- const allocator_type& __a = allocator_type())
- : _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) { }
- unordered_multimap(const unordered_multimap&) = default;
- unordered_multimap(const _Base& __x)
- : _Base(__x) { }
- unordered_multimap(unordered_multimap&&) = default;
- explicit
- unordered_multimap(const allocator_type& __a)
- : _Base(__a) { }
- unordered_multimap(const unordered_multimap& __ummap,
- const allocator_type& __a)
- : _Base(__ummap._M_base(), __a) { }
- unordered_multimap(unordered_multimap&& __ummap,
- const allocator_type& __a)
- : _Base(std::move(__ummap._M_base()), __a) { }
- 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) { }
- unordered_multimap(size_type __n, const allocator_type& __a)
- : unordered_multimap(__n, hasher(), key_equal(), __a)
- { }
- unordered_multimap(size_type __n, const hasher& __hf,
- const allocator_type& __a)
- : unordered_multimap(__n, __hf, key_equal(), __a)
- { }
- template<typename _InputIterator>
- unordered_multimap(_InputIterator __first, _InputIterator __last,
- size_type __n,
- const allocator_type& __a)
- : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a)
- { }
- template<typename _InputIterator>
- unordered_multimap(_InputIterator __first, _InputIterator __last,
- size_type __n, const hasher& __hf,
- const allocator_type& __a)
- : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a)
- { }
- unordered_multimap(initializer_list<value_type> __l,
- size_type __n,
- const allocator_type& __a)
- : unordered_multimap(__l, __n, hasher(), key_equal(), __a)
- { }
- unordered_multimap(initializer_list<value_type> __l,
- size_type __n, const hasher& __hf,
- const allocator_type& __a)
- : unordered_multimap(__l, __n, __hf, key_equal(), __a)
- { }
- unordered_multimap&
- operator=(const unordered_multimap&) = default;
- unordered_multimap&
- operator=(unordered_multimap&&) = default;
- unordered_multimap&
- operator=(initializer_list<value_type> __l)
- {
- this->_M_profile_destruct();
- _M_base() = __l;
- this->_M_profile_construct();
- return *this;
- }
- void
- clear() noexcept
- {
- this->_M_profile_destruct();
- _Base::clear();
- this->_M_profile_construct();
- }
- template<typename... _Args>
- iterator
- emplace(_Args&&... __args)
- {
- size_type __old_size = _Base::bucket_count();
- iterator __res
- = _Base::emplace(std::forward<_Args>(__args)...);
- this->_M_profile_resize(__old_size);
- return __res;
- }
- template<typename... _Args>
- iterator
- emplace_hint(const_iterator __it, _Args&&... __args)
- {
- size_type __old_size = _Base::bucket_count();
- iterator __res
- = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
- this->_M_profile_resize(__old_size);
- return __res;
- }
- void
- insert(std::initializer_list<value_type> __l)
- {
- size_type __old_size = _Base::bucket_count();
- _Base::insert(__l);
- this->_M_profile_resize(__old_size);
- }
- iterator
- insert(const value_type& __obj)
- {
- size_type __old_size = _Base::bucket_count();
- iterator __res = _Base::insert(__obj);
- this->_M_profile_resize(__old_size);
- return __res;
- }
- iterator
- insert(const_iterator __iter, const value_type& __v)
- {
- size_type __old_size = _Base::bucket_count();
- iterator __res = _Base::insert(__iter, __v);
- this->_M_profile_resize(__old_size);
- return __res;
- }
- template<typename _Pair, typename = typename
- std::enable_if<std::is_constructible<value_type,
- _Pair&&>::value>::type>
- iterator
- insert(_Pair&& __obj)
- {
- size_type __old_size = _Base::bucket_count();
- iterator __res = _Base::insert(std::forward<_Pair>(__obj));
- this->_M_profile_resize(__old_size);
- return __res;
- }
- template<typename _Pair, typename = typename
- std::enable_if<std::is_constructible<value_type,
- _Pair&&>::value>::type>
- iterator
- insert(const_iterator __iter, _Pair&& __v)
- {
- size_type __old_size = _Base::bucket_count();
- iterator __res = _Base::insert(__iter, std::forward<_Pair>(__v));
- this->_M_profile_resize(__old_size);
- return __res;
- }
- template<typename _InputIter>
- void
- insert(_InputIter __first, _InputIter __last)
- {
- size_type __old_size = _Base::bucket_count();
- _Base::insert(__first, __last);
- this->_M_profile_resize(__old_size);
- }
- void
- swap(unordered_multimap& __x)
- noexcept( noexcept(__x._M_base().swap(__x)) )
- {
- _Base::swap(__x._M_base());
- this->_M_swap(__x);
- }
- void
- rehash(size_type __n)
- {
- size_type __old_size = _Base::bucket_count();
- _Base::rehash(__n);
- this->_M_profile_resize(__old_size);
- }
- };
- template<typename _Key, typename _Tp, typename _Hash,
- typename _Pred, typename _Alloc>
- inline void
- swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
- unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
- noexcept(noexcept(__x.swap(__y)))
- { __x.swap(__y); }
- template<typename _Key, typename _Tp, typename _Hash,
- typename _Pred, typename _Alloc>
- inline bool
- operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
- const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
- { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
- template<typename _Key, typename _Tp, typename _Hash,
- typename _Pred, typename _Alloc>
- inline bool
- operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
- const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
- { return !(__x == __y); }
- } // namespace __profile
- } // namespace std
- #undef _GLIBCXX_BASE
- #undef _GLIBCXX_STD_BASE
- #endif // C++11
- #endif
|