OSDN Git Service

4af778bbf7c3a20cd7fce2a81df3e43315c042b5
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / profile / unordered_set
1 // Profiling unordered_set/unordered_multiset implementation -*- C++ -*-
2
3 // Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
4 //
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 2, or (at your option)
9 // any later version.
10
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.
15
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING.  If not, write to the Free
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 // USA.
20
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction.  Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License.  This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29
30 /** @file profile/unordered_set
31  *  This file is a GNU profile extension to the Standard C++ Library.
32  */
33
34 #ifndef _GLIBCXX_PROFILE_UNORDERED_SET
35 #define _GLIBCXX_PROFILE_UNORDERED_SET 1
36
37 #ifndef __GXX_EXPERIMENTAL_CXX0X__
38 # include <bits/c++0x_warning.h>
39 #else
40 # include <unordered_set>
41
42 #include <profile/base.h>
43
44 #define _GLIBCXX_BASE unordered_set<_Key, _Hash, _Pred, _Alloc>
45 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
46
47 namespace std _GLIBCXX_VISIBILITY(default)
48 {
49 namespace __profile
50 {
51   /** @brief Unordered_set wrapper with performance instrumentation.  */
52   template<typename _Key, 
53            typename _Hash  = std::hash<_Key>,
54            typename _Pred = std::equal_to<_Key>,
55            typename _Alloc =  std::allocator<_Key> >
56     class unordered_set
57     : public _GLIBCXX_STD_BASE
58     {
59       typedef typename _GLIBCXX_STD_BASE _Base;
60
61     public:
62       typedef typename _Base::size_type       size_type;
63       typedef typename _Base::hasher          hasher;
64       typedef typename _Base::key_equal       key_equal;
65       typedef typename _Base::allocator_type  allocator_type;
66       typedef typename _Base::key_type        key_type;
67       typedef typename _Base::value_type      value_type;
68       typedef typename _Base::difference_type difference_type;
69       typedef typename _Base::reference       reference;
70       typedef typename _Base::const_reference const_reference;
71
72       typedef typename _Base::iterator iterator;
73       typedef typename _Base::const_iterator const_iterator;
74
75       explicit
76       unordered_set(size_type __n = 10,
77                     const hasher& __hf = hasher(),
78                     const key_equal& __eql = key_equal(),
79                     const allocator_type& __a = allocator_type())
80       : _Base(__n, __hf, __eql, __a)
81       {
82         __profcxx_hashtable_construct(this, _Base::bucket_count());
83         __profcxx_hashtable_construct2(this);
84       }
85
86       template<typename _InputIterator>
87         unordered_set(_InputIterator __f, _InputIterator __l,
88                       size_type __n = 0,
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)
93       {
94         __profcxx_hashtable_construct(this, _Base::bucket_count());
95         __profcxx_hashtable_construct2(this);
96       }
97
98       unordered_set(const unordered_set& __x)
99       : _Base(__x) 
100       { 
101         __profcxx_hashtable_construct(this, _Base::bucket_count());
102         __profcxx_hashtable_construct2(this);
103       }
104
105       unordered_set(const _Base& __x)
106       : _Base(__x) 
107       { 
108         __profcxx_hashtable_construct(this, _Base::bucket_count());
109         __profcxx_hashtable_construct2(this);
110       }
111
112       unordered_set(unordered_set&& __x)
113       : _Base(std::move(__x)) 
114       { 
115         __profcxx_hashtable_construct(this, _Base::bucket_count());
116         __profcxx_hashtable_construct2(this);
117       }
118
119       unordered_set(initializer_list<value_type> __l,
120                     size_type __n = 0,
121                     const hasher& __hf = hasher(),
122                     const key_equal& __eql = key_equal(),
123                     const allocator_type& __a = allocator_type())
124       : _Base(__l, __n, __hf, __eql, __a) { }
125
126       unordered_set&
127       operator=(const unordered_set& __x)
128       {
129         *static_cast<_Base*>(this) = __x;
130         return *this;
131       }
132
133       unordered_set&
134       operator=(unordered_set&& __x)
135       {
136         // NB: DR 1204.
137         // NB: DR 675.
138         this->clear();
139         this->swap(__x);
140         return *this;
141       }
142
143       unordered_set&
144       operator=(initializer_list<value_type> __l)
145       {
146         this->clear();
147         this->insert(__l);
148         return *this;
149       }
150
151       ~unordered_set() noexcept
152       {
153         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
154                                      _Base::size());
155         _M_profile_destruct();
156       }
157
158       void
159       swap(unordered_set& __x)
160       {
161         _Base::swap(__x);
162       }
163
164       void
165       clear() noexcept
166       {
167         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
168                                      _Base::size());
169         _M_profile_destruct();
170         _Base::clear();
171       }
172
173       void
174       insert(std::initializer_list<value_type> __l)
175       { 
176         size_type __old_size =  _Base::bucket_count();
177         _Base::insert(__l); 
178         _M_profile_resize(__old_size,  _Base::bucket_count()); 
179       }
180
181       std::pair<iterator, bool>
182       insert(const value_type& __obj)
183       {
184         size_type __old_size = _Base::bucket_count();
185         std::pair<iterator, bool> __res = _Base::insert(__obj);
186         _M_profile_resize(__old_size,  _Base::bucket_count()); 
187         return __res;
188       }
189
190       iterator
191       insert(const_iterator __iter, const value_type& __v)
192       { 
193         size_type __old_size = _Base::bucket_count(); 
194         iterator __res = _Base::insert(__iter, __v);
195         _M_profile_resize(__old_size, _Base::bucket_count()); 
196         return __res;
197       }
198
199       std::pair<iterator, bool>
200       insert(value_type&& __obj)
201       {
202         size_type __old_size = _Base::bucket_count();
203         std::pair<iterator, bool> __res = _Base::insert(std::move(__obj));
204         _M_profile_resize(__old_size,  _Base::bucket_count()); 
205         return __res;
206       }
207
208       iterator
209       insert(const_iterator __iter, value_type&& __v)
210       { 
211         size_type __old_size = _Base::bucket_count();
212         iterator __res = _Base::insert(__iter, std::move(__v));
213         _M_profile_resize(__old_size, _Base::bucket_count()); 
214         return __res;
215       }
216
217       template<typename _InputIter>
218         void
219         insert(_InputIter __first, _InputIter __last)
220         {
221           size_type __old_size = _Base::bucket_count(); 
222           _Base::insert(__first, __last);
223           _M_profile_resize(__old_size,  _Base::bucket_count()); 
224         }
225
226       void
227       insert(const value_type* __first, const value_type* __last)
228       {
229         size_type __old_size = _Base::bucket_count(); 
230         _Base::insert(__first, __last);
231         _M_profile_resize(__old_size,  _Base::bucket_count()); 
232       }
233      
234       void rehash(size_type __n)
235       {
236         size_type __old_size =  _Base::bucket_count();
237         _Base::rehash(__n);
238         _M_profile_resize(__old_size,  _Base::bucket_count()); 
239       }
240
241     private:
242       _Base&
243       _M_base() noexcept       { return *this; }
244
245       const _Base&
246       _M_base() const noexcept { return *this; }
247
248       void
249       _M_profile_resize(size_type __old_size, size_type __new_size)
250       {
251         if (__old_size != __new_size)
252           __profcxx_hashtable_resize(this, __old_size, __new_size);
253       }
254
255       void
256       _M_profile_destruct()
257       {
258         size_type __hops = 0, __lc = 0, __chain = 0;
259         for (iterator __it = _M_base().begin(); __it != _M_base().end();
260              ++__it)
261         {
262           while (__it._M_cur_node->_M_next)
263             {
264               ++__chain;
265               ++__it;
266             }
267
268           if (__chain)
269             {
270               ++__chain;
271               __lc = __lc > __chain ? __lc : __chain;
272               __hops += __chain * (__chain - 1) / 2;
273               __chain = 0;
274             }
275         }
276         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops);
277       }
278
279    };
280
281   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
282     inline void
283     swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
284          unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
285     { __x.swap(__y); }
286
287   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
288     inline bool
289     operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
290                const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
291     { return __x._M_equal(__y); }
292
293   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
294     inline bool
295     operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
296                const unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
297     { return !(__x == __y); }
298
299 #undef _GLIBCXX_BASE
300 #undef _GLIBCXX_STD_BASE
301 #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE
302 #define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc>
303
304   /** @brief Unordered_multiset wrapper with performance instrumentation.  */
305   template<typename _Value,
306        typename _Hash  = std::hash<_Value>,
307        typename _Pred = std::equal_to<_Value>,
308        typename _Alloc =  std::allocator<_Value> >
309     class unordered_multiset
310     : public _GLIBCXX_STD_BASE
311     {
312       typedef typename _GLIBCXX_STD_BASE _Base;
313
314     public:
315       typedef typename _Base::size_type       size_type;
316       typedef typename _Base::hasher          hasher;
317       typedef typename _Base::key_equal       key_equal;
318       typedef typename _Base::allocator_type  allocator_type;
319       typedef typename _Base::key_type        key_type;
320       typedef typename _Base::value_type      value_type;
321       typedef typename _Base::difference_type difference_type;
322       typedef typename _Base::reference       reference;
323       typedef typename _Base::const_reference const_reference;
324
325       typedef typename _Base::iterator iterator;
326       typedef typename _Base::const_iterator const_iterator;
327
328       explicit
329       unordered_multiset(size_type __n = 10,
330                          const hasher& __hf = hasher(),
331                          const key_equal& __eql = key_equal(),
332                          const allocator_type& __a = allocator_type())
333       : _Base(__n, __hf, __eql, __a)
334       {
335         __profcxx_hashtable_construct(this, _Base::bucket_count());
336       }
337
338       template<typename _InputIterator>
339         unordered_multiset(_InputIterator __f, _InputIterator __l,
340                            size_type __n = 0,
341                            const hasher& __hf = hasher(),
342                            const key_equal& __eql = key_equal(),
343                            const allocator_type& __a = allocator_type())
344       : _Base(__f, __l, __n, __hf, __eql, __a)
345       {
346         __profcxx_hashtable_construct(this, _Base::bucket_count());
347       }
348
349       unordered_multiset(const unordered_multiset& __x)
350       : _Base(__x)
351       {
352         __profcxx_hashtable_construct(this, _Base::bucket_count());
353       }
354
355       unordered_multiset(const _Base& __x)
356       : _Base(__x)
357       {
358         __profcxx_hashtable_construct(this, _Base::bucket_count());
359       }
360
361       unordered_multiset(unordered_multiset&& __x)
362       : _Base(std::move(__x))
363       {
364         __profcxx_hashtable_construct(this, _Base::bucket_count());
365       }
366
367       unordered_multiset(initializer_list<value_type> __l,
368                          size_type __n = 0,
369                          const hasher& __hf = hasher(),
370                          const key_equal& __eql = key_equal(),
371                          const allocator_type& __a = allocator_type())
372       : _Base(__l, __n, __hf, __eql, __a) { }
373
374       unordered_multiset&
375       operator=(const unordered_multiset& __x)
376       {
377         *static_cast<_Base*>(this) = __x;
378         return *this;
379       }
380
381       unordered_multiset&
382       operator=(unordered_multiset&& __x)
383       {
384         // NB: DR 1204.
385         // NB: DR 675.
386         this->clear();
387         this->swap(__x);
388         return *this;
389       }
390
391       unordered_multiset&
392       operator=(initializer_list<value_type> __l)
393       {
394         this->clear();
395         this->insert(__l);
396         return *this;
397       }
398
399       ~unordered_multiset() noexcept
400       {
401         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
402                                      _Base::size());
403         _M_profile_destruct();
404       }
405
406       void
407       swap(unordered_multiset& __x)
408       {
409         _Base::swap(__x);
410       }
411
412       void
413       clear() noexcept
414       {
415         __profcxx_hashtable_destruct(this, _Base::bucket_count(), 
416                                      _Base::size());
417         _M_profile_destruct();
418         _Base::clear();
419       }
420
421       void
422       insert(std::initializer_list<value_type> __l)
423       { 
424         size_type __old_size =  _Base::bucket_count();
425         _Base::insert(__l); 
426         _M_profile_resize(__old_size,  _Base::bucket_count()); 
427       }
428
429       iterator
430       insert(const value_type& __obj)
431       {
432         size_type __old_size =  _Base::bucket_count();
433         iterator __res = _Base::insert(__obj);
434         _M_profile_resize(__old_size,  _Base::bucket_count()); 
435         return __res;
436       }
437
438       iterator
439       insert(const_iterator __iter, const value_type& __v)
440       {
441         size_type __old_size = _Base::bucket_count(); 
442         iterator __res = _Base::insert(__iter, __v);
443         _M_profile_resize(__old_size, _Base::bucket_count()); 
444         return __res;
445       }
446
447       iterator
448       insert(value_type&& __obj)
449       {
450         size_type __old_size =  _Base::bucket_count();
451         iterator __res = _Base::insert(std::move(__obj));
452         _M_profile_resize(__old_size,  _Base::bucket_count()); 
453         return __res;
454       }
455
456       iterator
457       insert(const_iterator __iter, value_type&& __v)
458       {
459         size_type __old_size = _Base::bucket_count(); 
460         iterator __res = _Base::insert(__iter, std::move(__v));
461         _M_profile_resize(__old_size, _Base::bucket_count()); 
462         return __res;
463       }
464
465       template<typename _InputIter>
466         void
467         insert(_InputIter __first, _InputIter __last)
468         {
469           size_type __old_size = _Base::bucket_count(); 
470           _Base::insert(__first, __last);
471           _M_profile_resize(__old_size,  _Base::bucket_count()); 
472         }
473
474       void
475       insert(const value_type* __first, const value_type* __last)
476       {
477         size_type __old_size = _Base::bucket_count(); 
478         _Base::insert(__first, __last);
479         _M_profile_resize(__old_size,  _Base::bucket_count()); 
480       }
481      
482       void rehash(size_type __n)
483       {
484         size_type __old_size =  _Base::bucket_count();
485         _Base::rehash(__n);
486         _M_profile_resize(__old_size,  _Base::bucket_count()); 
487       }
488
489     private:
490       _Base&
491       _M_base() noexcept       { return *this; }
492
493       const _Base&
494       _M_base() const noexcept { return *this; }
495
496       void
497       _M_profile_resize(size_type __old_size, size_type __new_size)
498       {
499         if (__old_size != __new_size)
500           __profcxx_hashtable_resize(this, __old_size, __new_size);
501       }
502
503       void
504       _M_profile_destruct()
505       {
506         size_type __hops = 0, __lc = 0, __chain = 0;
507         for (iterator __it = _M_base().begin(); __it != _M_base().end();
508              ++__it)
509         {
510           while (__it._M_cur_node->_M_next)
511             {
512              ++__chain;
513              ++__it;
514             }
515
516           if (__chain)
517             {
518               ++__chain;
519               __lc = __lc > __chain ? __lc : __chain;
520               __hops += __chain * (__chain - 1) / 2;
521               __chain = 0;
522             }
523         }
524         __profcxx_hashtable_destruct2(this, __lc,  _Base::size(), __hops);
525       }
526
527    };
528
529   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
530     inline void
531     swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
532          unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
533     { __x.swap(__y); }
534
535   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
536     inline bool
537     operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
538                const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
539     { return __x._M_equal(__y); }
540
541   template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
542     inline bool
543     operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
544                const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
545     { return !(__x == __y); }
546
547 } // namespace __profile
548 } // namespace std
549
550 #undef _GLIBCXX_BASE
551 #undef _GLIBCXX_STD_BASE
552
553 #endif // __GXX_EXPERIMENTAL_CXX0X__
554
555 #endif