libstdc++
unordered_set.h
Go to the documentation of this file.
00001 // unordered_set implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2010, 2011, 2013 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file bits/unordered_set.h
00026  *  This is an internal header file, included by other library headers.
00027  *  Do not attempt to use it directly. @headername{unordered_set}
00028  */
00029 
00030 #ifndef _UNORDERED_SET_H
00031 #define _UNORDERED_SET_H
00032 
00033 namespace std _GLIBCXX_VISIBILITY(default)
00034 {
00035 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
00036 
00037   // NB: When we get typedef templates these class definitions
00038   // will be unnecessary.
00039   template<class _Value,
00040        class _Hash = hash<_Value>,
00041        class _Pred = std::equal_to<_Value>,
00042        class _Alloc = std::allocator<_Value>,
00043        bool __cache_hash_code =
00044          __not_<__and_<is_integral<_Value>, is_empty<_Hash>,
00045                integral_constant<bool, !__is_final(_Hash)>,
00046                __detail::__is_noexcept_hash<_Value, _Hash>>>::value>
00047     class __unordered_set
00048     : public _Hashtable<_Value, _Value, _Alloc,
00049             std::_Identity<_Value>, _Pred,
00050             _Hash, __detail::_Mod_range_hashing,
00051             __detail::_Default_ranged_hash,
00052             __detail::_Prime_rehash_policy,
00053             __cache_hash_code, true, true>,
00054       __check_copy_constructible<_Alloc>
00055     {
00056       typedef _Hashtable<_Value, _Value, _Alloc,
00057              std::_Identity<_Value>, _Pred,
00058              _Hash, __detail::_Mod_range_hashing,
00059              __detail::_Default_ranged_hash,
00060              __detail::_Prime_rehash_policy,
00061              __cache_hash_code, true, true>
00062         _Base;
00063 
00064     public:
00065       typedef typename _Base::value_type      value_type;
00066       typedef typename _Base::size_type       size_type;
00067       typedef typename _Base::hasher          hasher;
00068       typedef typename _Base::key_equal       key_equal;
00069       typedef typename _Base::allocator_type  allocator_type;
00070       typedef typename _Base::iterator        iterator;
00071       typedef typename _Base::const_iterator  const_iterator;
00072 
00073       explicit
00074       __unordered_set(size_type __n = 10,
00075               const hasher& __hf = hasher(),
00076               const key_equal& __eql = key_equal(),
00077               const allocator_type& __a = allocator_type())
00078       : _Base(__n, __hf, __detail::_Mod_range_hashing(),
00079           __detail::_Default_ranged_hash(), __eql,
00080           std::_Identity<value_type>(), __a)
00081       { }
00082 
00083       template<typename _InputIterator>
00084         __unordered_set(_InputIterator __f, _InputIterator __l, 
00085             size_type __n = 0,
00086             const hasher& __hf = hasher(), 
00087             const key_equal& __eql = key_equal(), 
00088             const allocator_type& __a = allocator_type())
00089     : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(),
00090         __detail::_Default_ranged_hash(), __eql,
00091         std::_Identity<value_type>(), __a)
00092         { }
00093 
00094       __unordered_set(initializer_list<value_type> __l,
00095               size_type __n = 0,
00096               const hasher& __hf = hasher(),
00097               const key_equal& __eql = key_equal(),
00098               const allocator_type& __a = allocator_type())
00099       : _Base(__l.begin(), __l.end(), __n, __hf,
00100           __detail::_Mod_range_hashing(),
00101           __detail::_Default_ranged_hash(), __eql,
00102           std::_Identity<value_type>(), __a)
00103       { }
00104 
00105       __unordered_set&
00106       operator=(initializer_list<value_type> __l)
00107       {
00108     this->clear();
00109     this->insert(__l.begin(), __l.end());
00110     return *this;
00111       }
00112 
00113       using _Base::insert;
00114 
00115       std::pair<iterator, bool>
00116       insert(value_type&& __v)
00117       { return this->_M_insert(std::move(__v), std::true_type()); }
00118 
00119       iterator
00120       insert(const_iterator, value_type&& __v)
00121       { return insert(std::move(__v)).first; }
00122     };
00123 
00124   template<class _Value,
00125        class _Hash = hash<_Value>,
00126        class _Pred = std::equal_to<_Value>,
00127        class _Alloc = std::allocator<_Value>,
00128        bool __cache_hash_code =
00129          __not_<__and_<is_integral<_Value>, is_empty<_Hash>,
00130                integral_constant<bool, !__is_final(_Hash)>,
00131                __detail::__is_noexcept_hash<_Value, _Hash>>>::value>
00132     class __unordered_multiset
00133     : public _Hashtable<_Value, _Value, _Alloc,
00134             std::_Identity<_Value>, _Pred,
00135             _Hash, __detail::_Mod_range_hashing,
00136             __detail::_Default_ranged_hash,
00137             __detail::_Prime_rehash_policy,
00138             __cache_hash_code, true, false>,
00139       __check_copy_constructible<_Alloc>
00140     {
00141       typedef _Hashtable<_Value, _Value, _Alloc,
00142              std::_Identity<_Value>, _Pred,
00143              _Hash, __detail::_Mod_range_hashing,
00144              __detail::_Default_ranged_hash,
00145              __detail::_Prime_rehash_policy,
00146              __cache_hash_code, true, false>
00147         _Base;
00148 
00149     public:
00150       typedef typename _Base::value_type      value_type;
00151       typedef typename _Base::size_type       size_type;
00152       typedef typename _Base::hasher          hasher;
00153       typedef typename _Base::key_equal       key_equal;
00154       typedef typename _Base::allocator_type  allocator_type;
00155       typedef typename _Base::iterator        iterator;
00156       typedef typename _Base::const_iterator  const_iterator;
00157 
00158       explicit
00159       __unordered_multiset(size_type __n = 10,
00160                const hasher& __hf = hasher(),
00161                const key_equal& __eql = key_equal(),
00162                const allocator_type& __a = allocator_type())
00163       : _Base(__n, __hf, __detail::_Mod_range_hashing(),
00164           __detail::_Default_ranged_hash(), __eql,
00165           std::_Identity<value_type>(), __a)
00166       { }
00167 
00168 
00169       template<typename _InputIterator>
00170         __unordered_multiset(_InputIterator __f, _InputIterator __l, 
00171                  size_type __n = 0,
00172                  const hasher& __hf = hasher(), 
00173                  const key_equal& __eql = key_equal(), 
00174                  const allocator_type& __a = allocator_type())
00175     : _Base(__f, __l, __n, __hf, __detail::_Mod_range_hashing(),
00176         __detail::_Default_ranged_hash(), __eql,
00177         std::_Identity<value_type>(), __a)
00178         { }
00179 
00180       __unordered_multiset(initializer_list<value_type> __l,
00181                size_type __n = 0,
00182                const hasher& __hf = hasher(),
00183                const key_equal& __eql = key_equal(),
00184                const allocator_type& __a = allocator_type())
00185       : _Base(__l.begin(), __l.end(), __n, __hf,
00186           __detail::_Mod_range_hashing(),
00187           __detail::_Default_ranged_hash(), __eql,
00188           std::_Identity<value_type>(), __a)
00189       { }
00190 
00191       __unordered_multiset&
00192       operator=(initializer_list<value_type> __l)
00193       {
00194     this->clear();
00195     this->insert(__l.begin(), __l.end());
00196     return *this;
00197       }
00198 
00199       using _Base::insert;
00200 
00201       iterator
00202       insert(value_type&& __v)
00203       { return this->_M_insert(std::move(__v), std::false_type()); }
00204 
00205       iterator
00206       insert(const_iterator, value_type&& __v)
00207       { return insert(std::move(__v)); }
00208     };
00209 
00210   template<class _Value, class _Hash, class _Pred, class _Alloc,
00211        bool __cache_hash_code>
00212     inline void
00213     swap(__unordered_set<_Value, _Hash, _Pred, _Alloc, __cache_hash_code>& __x,
00214      __unordered_set<_Value, _Hash, _Pred, _Alloc, __cache_hash_code>& __y)
00215     { __x.swap(__y); }
00216 
00217   template<class _Value, class _Hash, class _Pred, class _Alloc,
00218        bool __cache_hash_code>
00219     inline void
00220     swap(__unordered_multiset<_Value, _Hash, _Pred,
00221      _Alloc, __cache_hash_code>& __x,
00222      __unordered_multiset<_Value, _Hash, _Pred,
00223      _Alloc, __cache_hash_code>& __y)
00224     { __x.swap(__y); }
00225 
00226   template<class _Value, class _Hash, class _Pred, class _Alloc,
00227        bool __cache_hash_code>
00228     inline bool
00229     operator==(const __unordered_set<_Value, _Hash, _Pred, _Alloc,
00230            __cache_hash_code>& __x,
00231            const __unordered_set<_Value, _Hash, _Pred, _Alloc,
00232            __cache_hash_code>& __y)
00233     { return __x._M_equal(__y); }
00234 
00235   template<class _Value, class _Hash, class _Pred, class _Alloc,
00236        bool __cache_hash_code>
00237     inline bool
00238     operator!=(const __unordered_set<_Value, _Hash, _Pred, _Alloc,
00239            __cache_hash_code>& __x,
00240            const __unordered_set<_Value, _Hash, _Pred, _Alloc,
00241            __cache_hash_code>& __y)
00242     { return !(__x == __y); }
00243 
00244   template<class _Value, class _Hash, class _Pred, class _Alloc,
00245        bool __cache_hash_code>
00246     inline bool
00247     operator==(const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
00248            __cache_hash_code>& __x,
00249            const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
00250            __cache_hash_code>& __y)
00251     { return __x._M_equal(__y); }
00252 
00253   template<class _Value, class _Hash, class _Pred, class _Alloc,
00254        bool __cache_hash_code>
00255     inline bool
00256     operator!=(const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
00257            __cache_hash_code>& __x,
00258            const __unordered_multiset<_Value, _Hash, _Pred, _Alloc,
00259            __cache_hash_code>& __y)
00260     { return !(__x == __y); }
00261 
00262   /**
00263    *  @brief A standard container composed of unique keys (containing
00264    *  at most one of each key value) in which the elements' keys are
00265    *  the elements themselves.
00266    *
00267    *  @ingroup unordered_associative_containers
00268    *
00269    *  Meets the requirements of a <a href="tables.html#65">container</a>, and
00270    *  <a href="tables.html#xx">unordered associative container</a>
00271    *
00272    *  @param  Value  Type of key objects.
00273    *  @param  Hash  Hashing function object type, defaults to hash<Value>.
00274    *  @param  Pred  Predicate function object type, defaults to equal_to<Value>.
00275    *  @param  Alloc  Allocator type, defaults to allocator<Key>.
00276    */
00277   template<class _Value,
00278        class _Hash = hash<_Value>,
00279        class _Pred = std::equal_to<_Value>,
00280        class _Alloc = std::allocator<_Value> >
00281     class unordered_set
00282     : public __unordered_set<_Value, _Hash, _Pred, _Alloc>
00283     {
00284       typedef __unordered_set<_Value, _Hash, _Pred, _Alloc>  _Base;
00285 
00286     public:
00287       typedef typename _Base::value_type      value_type;
00288       typedef typename _Base::size_type       size_type;
00289       typedef typename _Base::hasher          hasher;
00290       typedef typename _Base::key_equal       key_equal;
00291       typedef typename _Base::allocator_type  allocator_type;
00292       
00293       explicit
00294       unordered_set(size_type __n = 10,
00295             const hasher& __hf = hasher(),
00296             const key_equal& __eql = key_equal(),
00297             const allocator_type& __a = allocator_type())
00298       : _Base(__n, __hf, __eql, __a)
00299       { }
00300 
00301       template<typename _InputIterator>
00302         unordered_set(_InputIterator __f, _InputIterator __l, 
00303               size_type __n = 0,
00304               const hasher& __hf = hasher(), 
00305               const key_equal& __eql = key_equal(), 
00306               const allocator_type& __a = allocator_type())
00307     : _Base(__f, __l, __n, __hf, __eql, __a)
00308         { }
00309 
00310       unordered_set(initializer_list<value_type> __l,
00311             size_type __n = 0,
00312             const hasher& __hf = hasher(),
00313             const key_equal& __eql = key_equal(),
00314             const allocator_type& __a = allocator_type())
00315       : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
00316       { }
00317 
00318       unordered_set&
00319       operator=(initializer_list<value_type> __l)
00320       {
00321     this->clear();
00322     this->insert(__l.begin(), __l.end());
00323     return *this;
00324       }
00325     };
00326 
00327   /**
00328    *  @brief A standard container composed of equivalent keys
00329    *  (possibly containing multiple of each key value) in which the
00330    *  elements' keys are the elements themselves.
00331    *
00332    *  @ingroup unordered_associative_containers
00333    *
00334    *  Meets the requirements of a <a href="tables.html#65">container</a>, and
00335    *  <a href="tables.html#xx">unordered associative container</a>
00336    *
00337    *  @param  Value  Type of key objects.
00338    *  @param  Hash  Hashing function object type, defaults to hash<Value>.
00339    *  @param  Pred  Predicate function object type, defaults to equal_to<Value>.
00340    *  @param  Alloc  Allocator type, defaults to allocator<Key>.
00341    */
00342   template<class _Value,
00343        class _Hash = hash<_Value>,
00344        class _Pred = std::equal_to<_Value>,
00345        class _Alloc = std::allocator<_Value> >
00346     class unordered_multiset
00347     : public __unordered_multiset<_Value, _Hash, _Pred, _Alloc>
00348     {
00349       typedef __unordered_multiset<_Value, _Hash, _Pred, _Alloc>  _Base;
00350 
00351     public:
00352       typedef typename _Base::value_type      value_type;
00353       typedef typename _Base::size_type       size_type;
00354       typedef typename _Base::hasher          hasher;
00355       typedef typename _Base::key_equal       key_equal;
00356       typedef typename _Base::allocator_type  allocator_type;
00357       
00358       explicit
00359       unordered_multiset(size_type __n = 10,
00360              const hasher& __hf = hasher(),
00361              const key_equal& __eql = key_equal(),
00362              const allocator_type& __a = allocator_type())
00363       : _Base(__n, __hf, __eql, __a)
00364       { }
00365 
00366 
00367       template<typename _InputIterator>
00368         unordered_multiset(_InputIterator __f, _InputIterator __l, 
00369                size_type __n = 0,
00370                const hasher& __hf = hasher(), 
00371                const key_equal& __eql = key_equal(), 
00372                const allocator_type& __a = allocator_type())
00373     : _Base(__f, __l, __n, __hf, __eql, __a)
00374         { }
00375 
00376       unordered_multiset(initializer_list<value_type> __l,
00377              size_type __n = 0,
00378              const hasher& __hf = hasher(),
00379              const key_equal& __eql = key_equal(),
00380              const allocator_type& __a = allocator_type())
00381       : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
00382       { }
00383 
00384       unordered_multiset&
00385       operator=(initializer_list<value_type> __l)
00386       {
00387     this->clear();
00388     this->insert(__l.begin(), __l.end());
00389     return *this;
00390       }
00391     };
00392 
00393   template<class _Value, class _Hash, class _Pred, class _Alloc>
00394     inline void
00395     swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
00396      unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
00397     { __x.swap(__y); }
00398 
00399   template<class _Value, class _Hash, class _Pred, class _Alloc>
00400     inline void
00401     swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
00402      unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
00403     { __x.swap(__y); }
00404 
00405   template<class _Value, class _Hash, class _Pred, class _Alloc>
00406     inline bool
00407     operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
00408            const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
00409     { return __x._M_equal(__y); }
00410 
00411   template<class _Value, class _Hash, class _Pred, class _Alloc>
00412     inline bool
00413     operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
00414            const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
00415     { return !(__x == __y); }
00416 
00417   template<class _Value, class _Hash, class _Pred, class _Alloc>
00418     inline bool
00419     operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
00420            const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
00421     { return __x._M_equal(__y); }
00422 
00423   template<class _Value, class _Hash, class _Pred, class _Alloc>
00424     inline bool
00425     operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
00426            const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
00427     { return !(__x == __y); }
00428 
00429 _GLIBCXX_END_NAMESPACE_CONTAINER
00430 } // namespace std
00431 
00432 #endif /* _UNORDERED_SET_H */
00433