1 // Profiling unordered_set/unordered_multiset implementation -*- C++ -*-
 
    3 // Copyright (C) 2009-2014 Free Software Foundation, Inc.
 
    5 // This file is part of the GNU ISO C++ Library.  This library is free
 
    6 // software; you can redistribute it and/or modify it under the
 
    7 // terms of the GNU General Public License as published by the
 
    8 // Free Software Foundation; either version 3, or (at your option)
 
   11 // This library is distributed in the hope that it will be useful,
 
   12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 
   13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
   14 // GNU General Public License for more details.
 
   16 // Under Section 7 of GPL version 3, you are granted additional
 
   17 // permissions described in the GCC Runtime Library Exception, version
 
   18 // 3.1, as published by the Free Software Foundation.
 
   20 // You should have received a copy of the GNU General Public License along
 
   21 // with this library; see the file COPYING3.  If not see
 
   22 // <http://www.gnu.org/licenses/>.
 
   24 /** @file profile/unordered_set
 
   25  *  This file is a GNU profile extension to the Standard C++ Library.
 
   28 #ifndef _GLIBCXX_PROFILE_UNORDERED_SET
 
   29 #define _GLIBCXX_PROFILE_UNORDERED_SET 1
 
   31 #if __cplusplus < 201103L
 
   32 # include <bits/c++0x_warning.h>
 
   34 # include <unordered_set>
 
   36 #include <profile/base.h>
 
   37 #include <profile/unordered_base.h>
 
   39 #define _GLIBCXX_BASE unordered_set<_Key, _Hash, _Pred, _Alloc>
 
   40 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
 
   42 namespace std _GLIBCXX_VISIBILITY(default)
 
   46   /** @brief Unordered_set wrapper with performance instrumentation.  */
 
   47   template<typename _Key, 
 
   48       typename _Hash = std::hash<_Key>,
 
   49       typename _Pred = std::equal_to<_Key>,
 
   50       typename _Alloc =  std::allocator<_Key> >
 
   52     : public _GLIBCXX_STD_BASE,
 
   53       public _Unordered_profile<unordered_set<_Key, _Hash, _Pred, _Alloc>,
 
   56       typedef _GLIBCXX_STD_BASE _Base;
 
   59       _M_base() noexcept       { return *this; }
 
   62       _M_base() const noexcept { return *this; }
 
   65       typedef typename _Base::size_type       size_type;
 
   66       typedef typename _Base::hasher          hasher;
 
   67       typedef typename _Base::key_equal       key_equal;
 
   68       typedef typename _Base::allocator_type  allocator_type;
 
   69       typedef typename _Base::key_type        key_type;
 
   70       typedef typename _Base::value_type      value_type;
 
   71       typedef typename _Base::difference_type difference_type;
 
   72       typedef typename _Base::reference       reference;
 
   73       typedef typename _Base::const_reference const_reference;
 
   75       typedef typename _Base::iterator iterator;
 
   76       typedef typename _Base::const_iterator const_iterator;
 
   79       unordered_set(size_type __n = 10,
 
   80            const hasher& __hf = hasher(),
 
   81            const key_equal& __eql = key_equal(),
 
   82            const allocator_type& __a = allocator_type())
 
   83    : _Base(__n, __hf, __eql, __a)
 
   86       template<typename _InputIterator>
 
   87         unordered_set(_InputIterator __f, _InputIterator __l,
 
   89              const hasher& __hf = hasher(),
 
   90              const key_equal& __eql = key_equal(),
 
   91              const allocator_type& __a = allocator_type())
 
   92      : _Base(__f, __l, __n, __hf, __eql, __a)
 
   95       unordered_set(const unordered_set&) = default;
 
   97       unordered_set(const _Base& __x)
 
  101       unordered_set(unordered_set&&) = default;
 
  104       unordered_set(const allocator_type& __a)
 
  108       unordered_set(const unordered_set& __uset,
 
  109            const allocator_type& __a)
 
  110    : _Base(__uset._M_base(), __a)
 
  113       unordered_set(unordered_set&& __uset,
 
  114            const allocator_type& __a)
 
  115    : _Base(std::move(__uset._M_base()), __a)
 
  118       unordered_set(initializer_list<value_type> __l,
 
  120            const hasher& __hf = hasher(),
 
  121            const key_equal& __eql = key_equal(),
 
  122            const allocator_type& __a = allocator_type())
 
  123       : _Base(__l, __n, __hf, __eql, __a)
 
  127       operator=(const unordered_set&) = default;
 
  130       operator=(unordered_set&&) = default;
 
  133       operator=(initializer_list<value_type> __l)
 
  140       swap(unordered_set& __x)
 
  141       noexcept( noexcept(__x._M_base().swap(__x)) )
 
  142       { _Base::swap(__x); }
 
  147         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
 
  149         this->_M_profile_destruct();
 
  153       template<typename... _Args>
 
  154    std::pair<iterator, bool>
 
  155    emplace(_Args&&... __args)
 
  157      size_type __old_size = _Base::bucket_count();
 
  158      std::pair<iterator, bool> __res
 
  159        = _Base::emplace(std::forward<_Args>(__args)...);
 
  160      _M_profile_resize(__old_size);
 
  164       template<typename... _Args>
 
  166    emplace_hint(const_iterator __it, _Args&&... __args)
 
  168      size_type __old_size = _Base::bucket_count();
 
  170        = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
 
  171      _M_profile_resize(__old_size);
 
  176       insert(std::initializer_list<value_type> __l)
 
  178         size_type __old_size = _Base::bucket_count();
 
  180         _M_profile_resize(__old_size); 
 
  183       std::pair<iterator, bool>
 
  184       insert(const value_type& __obj)
 
  186         size_type __old_size = _Base::bucket_count();
 
  187         std::pair<iterator, bool> __res = _Base::insert(__obj);
 
  188         _M_profile_resize(__old_size); 
 
  193       insert(const_iterator __iter, const value_type& __v)
 
  195         size_type __old_size = _Base::bucket_count(); 
 
  196         iterator __res = _Base::insert(__iter, __v);
 
  197         _M_profile_resize(__old_size); 
 
  201       std::pair<iterator, bool>
 
  202       insert(value_type&& __obj)
 
  204         size_type __old_size = _Base::bucket_count();
 
  205         std::pair<iterator, bool> __res = _Base::insert(std::move(__obj));
 
  206         _M_profile_resize(__old_size); 
 
  211       insert(const_iterator __iter, value_type&& __v)
 
  213         size_type __old_size = _Base::bucket_count();
 
  214         iterator __res = _Base::insert(__iter, std::move(__v));
 
  215         _M_profile_resize(__old_size); 
 
  219       template<typename _InputIter>
 
  221         insert(_InputIter __first, _InputIter __last)
 
  223      size_type __old_size = _Base::bucket_count(); 
 
  224      _Base::insert(__first, __last);
 
  225      _M_profile_resize(__old_size); 
 
  229       rehash(size_type __n)
 
  231         size_type __old_size = _Base::bucket_count();
 
  233         _M_profile_resize(__old_size); 
 
  238       _M_profile_resize(size_type __old_size)
 
  240    size_type __new_size = _Base::bucket_count();
 
  241    if (__old_size != __new_size)
 
  242      __profcxx_hashtable_resize(this, __old_size, __new_size);
 
  246   template<typename _Key, typename _Hash, typename _Pred, typename _Alloc>
 
  248     swap(unordered_set<_Key, _Hash, _Pred, _Alloc>& __x,
 
  249     unordered_set<_Key, _Hash, _Pred, _Alloc>& __y)
 
  252   template<typename _Key, typename _Hash, typename _Pred, typename _Alloc>
 
  254     operator==(const unordered_set<_Key, _Hash, _Pred, _Alloc>& __x,
 
  255           const unordered_set<_Key, _Hash, _Pred, _Alloc>& __y)
 
  256     { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
 
  258   template<typename _Key, typename _Hash, typename _Pred, typename _Alloc>
 
  260     operator!=(const unordered_set<_Key, _Hash, _Pred, _Alloc>& __x,
 
  261           const unordered_set<_Key, _Hash, _Pred, _Alloc>& __y)
 
  262     { return !(__x == __y); }
 
  265 #undef _GLIBCXX_STD_BASE
 
  266 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
 
  267 #define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc>
 
  269   /** @brief Unordered_multiset wrapper with performance instrumentation.  */
 
  270   template<typename _Value,
 
  271       typename _Hash = std::hash<_Value>,
 
  272       typename _Pred = std::equal_to<_Value>,
 
  273       typename _Alloc =  std::allocator<_Value> >
 
  274     class unordered_multiset
 
  275     : public _GLIBCXX_STD_BASE,
 
  276       public _Unordered_profile<unordered_multiset<_Value,
 
  277                           _Hash, _Pred, _Alloc>,
 
  280       typedef _GLIBCXX_STD_BASE _Base;
 
  283       _M_base() noexcept       { return *this; }
 
  286       _M_base() const noexcept { return *this; }
 
  289       typedef typename _Base::size_type       size_type;
 
  290       typedef typename _Base::hasher          hasher;
 
  291       typedef typename _Base::key_equal       key_equal;
 
  292       typedef typename _Base::allocator_type  allocator_type;
 
  293       typedef typename _Base::key_type        key_type;
 
  294       typedef typename _Base::value_type      value_type;
 
  295       typedef typename _Base::difference_type difference_type;
 
  296       typedef typename _Base::reference       reference;
 
  297       typedef typename _Base::const_reference const_reference;
 
  299       typedef typename _Base::iterator iterator;
 
  300       typedef typename _Base::const_iterator const_iterator;
 
  303       unordered_multiset(size_type __n = 10,
 
  304             const hasher& __hf = hasher(),
 
  305             const key_equal& __eql = key_equal(),
 
  306             const allocator_type& __a = allocator_type())
 
  307    : _Base(__n, __hf, __eql, __a)
 
  310       template<typename _InputIterator>
 
  311         unordered_multiset(_InputIterator __f, _InputIterator __l,
 
  313               const hasher& __hf = hasher(),
 
  314               const key_equal& __eql = key_equal(),
 
  315               const allocator_type& __a = allocator_type())
 
  316      : _Base(__f, __l, __n, __hf, __eql, __a)
 
  319       unordered_multiset(const unordered_multiset&) = default;
 
  321       unordered_multiset(const _Base& __x)
 
  325       unordered_multiset(unordered_multiset&&) = default;
 
  328       unordered_multiset(const allocator_type& __a)
 
  332       unordered_multiset(const unordered_multiset& __umset,
 
  333             const allocator_type& __a)
 
  334    : _Base(__umset._M_base(), __a)
 
  337       unordered_multiset(unordered_multiset&& __umset,
 
  338             const allocator_type& __a)
 
  339    : _Base(std::move(__umset._M_base()), __a)
 
  342       unordered_multiset(initializer_list<value_type> __l,
 
  344             const hasher& __hf = hasher(),
 
  345             const key_equal& __eql = key_equal(),
 
  346             const allocator_type& __a = allocator_type())
 
  347    : _Base(__l, __n, __hf, __eql, __a)
 
  351       operator=(const unordered_multiset&) = default;
 
  354       operator=(unordered_multiset&&) = default;
 
  357       operator=(initializer_list<value_type> __l)
 
  364       swap(unordered_multiset& __x)
 
  365       noexcept( noexcept(__x._M_base().swap(__x)) )
 
  366       { _Base::swap(__x); }
 
  371         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
 
  373         this->_M_profile_destruct();
 
  377       template<typename... _Args>
 
  379    emplace(_Args&&... __args)
 
  381      size_type __old_size = _Base::bucket_count();
 
  382      iterator __res = _Base::emplace(std::forward<_Args>(__args)...);
 
  383      _M_profile_resize(__old_size);
 
  387       template<typename... _Args>
 
  389    emplace_hint(const_iterator __it, _Args&&... __args)
 
  391      size_type __old_size = _Base::bucket_count();
 
  393        = _Base::emplace_hint(__it, std::forward<_Args>(__args)...);
 
  394      _M_profile_resize(__old_size);
 
  399       insert(std::initializer_list<value_type> __l)
 
  401         size_type __old_size = _Base::bucket_count();
 
  403         _M_profile_resize(__old_size); 
 
  407       insert(const value_type& __obj)
 
  409         size_type __old_size = _Base::bucket_count();
 
  410         iterator __res = _Base::insert(__obj);
 
  411         _M_profile_resize(__old_size); 
 
  416       insert(const_iterator __iter, const value_type& __v)
 
  418         size_type __old_size = _Base::bucket_count(); 
 
  419         iterator __res = _Base::insert(__iter, __v);
 
  420         _M_profile_resize(__old_size); 
 
  425       insert(value_type&& __obj)
 
  427    size_type __old_size = _Base::bucket_count();
 
  428         iterator __res = _Base::insert(std::move(__obj));
 
  429         _M_profile_resize(__old_size); 
 
  434       insert(const_iterator __iter, value_type&& __v)
 
  436         size_type __old_size = _Base::bucket_count(); 
 
  437         iterator __res = _Base::insert(__iter, std::move(__v));
 
  438         _M_profile_resize(__old_size); 
 
  442       template<typename _InputIter>
 
  444         insert(_InputIter __first, _InputIter __last)
 
  446      size_type __old_size = _Base::bucket_count(); 
 
  447      _Base::insert(__first, __last);
 
  448      _M_profile_resize(__old_size); 
 
  452       rehash(size_type __n)
 
  454         size_type __old_size = _Base::bucket_count();
 
  456         _M_profile_resize(__old_size); 
 
  461       _M_profile_resize(size_type __old_size)
 
  463    size_type __new_size = _Base::bucket_count();
 
  464         if (__old_size != __new_size)
 
  465           __profcxx_hashtable_resize(this, __old_size, __new_size);
 
  469   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
 
  471     swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
 
  472     unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
 
  475   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
 
  477     operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
 
  478           const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
 
  479     { return static_cast<const _GLIBCXX_STD_BASE&>(__x) == __y; }
 
  481   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
 
  483     operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
 
  484           const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
 
  485     { return !(__x == __y); }
 
  487 } // namespace __profile
 
  491 #undef _GLIBCXX_STD_BASE