197403Sobrien// Hashing set implementation -*- C++ -*-
297403Sobrien
3169691Skan// Copyright (C) 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
497403Sobrien//
597403Sobrien// This file is part of the GNU ISO C++ Library.  This library is free
697403Sobrien// software; you can redistribute it and/or modify it under the
797403Sobrien// terms of the GNU General Public License as published by the
897403Sobrien// Free Software Foundation; either version 2, or (at your option)
997403Sobrien// any later version.
1097403Sobrien
1197403Sobrien// This library is distributed in the hope that it will be useful,
1297403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of
1397403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1497403Sobrien// GNU General Public License for more details.
1597403Sobrien
1697403Sobrien// You should have received a copy of the GNU General Public License along
1797403Sobrien// with this library; see the file COPYING.  If not, write to the Free
18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
1997403Sobrien// USA.
2097403Sobrien
2197403Sobrien// As a special exception, you may use this file as part of a free software
2297403Sobrien// library without restriction.  Specifically, if other files instantiate
2397403Sobrien// templates or use macros or inline functions from this file, or you compile
2497403Sobrien// this file and link it with other files to produce an executable, this
2597403Sobrien// file does not by itself cause the resulting executable to be covered by
2697403Sobrien// the GNU General Public License.  This exception does not however
2797403Sobrien// invalidate any other reasons why the executable file might be covered by
2897403Sobrien// the GNU General Public License.
2997403Sobrien
3097403Sobrien/*
3197403Sobrien * Copyright (c) 1996
3297403Sobrien * Silicon Graphics Computer Systems, Inc.
3397403Sobrien *
3497403Sobrien * Permission to use, copy, modify, distribute and sell this software
3597403Sobrien * and its documentation for any purpose is hereby granted without fee,
3697403Sobrien * provided that the above copyright notice appear in all copies and
3797403Sobrien * that both that copyright notice and this permission notice appear
3897403Sobrien * in supporting documentation.  Silicon Graphics makes no
3997403Sobrien * representations about the suitability of this software for any
4097403Sobrien * purpose.  It is provided "as is" without express or implied warranty.
4197403Sobrien *
4297403Sobrien *
4397403Sobrien * Copyright (c) 1994
4497403Sobrien * Hewlett-Packard Company
4597403Sobrien *
4697403Sobrien * Permission to use, copy, modify, distribute and sell this software
4797403Sobrien * and its documentation for any purpose is hereby granted without fee,
4897403Sobrien * provided that the above copyright notice appear in all copies and
4997403Sobrien * that both that copyright notice and this permission notice appear
5097403Sobrien * in supporting documentation.  Hewlett-Packard Company makes no
5197403Sobrien * representations about the suitability of this software for any
5297403Sobrien * purpose.  It is provided "as is" without express or implied warranty.
5397403Sobrien *
5497403Sobrien */
5597403Sobrien
5697403Sobrien/** @file ext/hash_set
5797403Sobrien *  This file is a GNU extension to the Standard C++ Library (possibly
58169691Skan *  containing extensions from the HP/SGI STL subset).
5997403Sobrien */
6097403Sobrien
61132720Skan#ifndef _HASH_SET
62132720Skan#define _HASH_SET 1
6397403Sobrien
64169691Skan#include <bits/c++config.h>
65132720Skan#include <ext/hashtable.h>
6697403Sobrien#include <bits/concept_check.h>
6797403Sobrien
68169691Skan_GLIBCXX_BEGIN_NESTED_NAMESPACE(__gnu_cxx, _GLIBCXX_EXT)
69169691Skan
70132720Skan  using std::equal_to;
71132720Skan  using std::allocator;
72132720Skan  using std::pair;
73132720Skan  using std::_Identity;
7497403Sobrien
75169691Skan  /**
76169691Skan   *  This is an SGI extension.
77169691Skan   *  @ingroup SGIextensions
78169691Skan   *  @doctodo
79169691Skan   */
80169691Skan  template<class _Value, class _HashFcn  = hash<_Value>,
81169691Skan	   class _EqualKey = equal_to<_Value>,
82169691Skan	   class _Alloc = allocator<_Value> >
83169691Skan    class hash_set
84169691Skan    {
85169691Skan      // concept requirements
86169691Skan      __glibcxx_class_requires(_Value, _SGIAssignableConcept)
87169691Skan      __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
88169691Skan      __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
8997403Sobrien
90169691Skan    private:
91169691Skan      typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
92169691Skan			_EqualKey, _Alloc> _Ht;
93169691Skan      _Ht _M_ht;
9497403Sobrien
95169691Skan    public:
96169691Skan      typedef typename _Ht::key_type key_type;
97169691Skan      typedef typename _Ht::value_type value_type;
98169691Skan      typedef typename _Ht::hasher hasher;
99169691Skan      typedef typename _Ht::key_equal key_equal;
100169691Skan      
101169691Skan      typedef typename _Ht::size_type size_type;
102169691Skan      typedef typename _Ht::difference_type difference_type;
103169691Skan      typedef typename _Alloc::pointer pointer;
104169691Skan      typedef typename _Alloc::const_pointer const_pointer;
105169691Skan      typedef typename _Alloc::reference reference;
106169691Skan      typedef typename _Alloc::const_reference const_reference;
107169691Skan      
108169691Skan      typedef typename _Ht::const_iterator iterator;
109169691Skan      typedef typename _Ht::const_iterator const_iterator;
110169691Skan      
111169691Skan      typedef typename _Ht::allocator_type allocator_type;
112169691Skan      
113169691Skan      hasher
114169691Skan      hash_funct() const
115169691Skan      { return _M_ht.hash_funct(); }
11697403Sobrien
117169691Skan      key_equal
118169691Skan      key_eq() const
119169691Skan      { return _M_ht.key_eq(); }
12097403Sobrien
121169691Skan      allocator_type
122169691Skan      get_allocator() const
123169691Skan      { return _M_ht.get_allocator(); }
12497403Sobrien
125169691Skan    public:
126169691Skan      hash_set()
127169691Skan      : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
12897403Sobrien
129169691Skan      explicit
130169691Skan      hash_set(size_type __n)
131169691Skan      : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
13297403Sobrien
133169691Skan      hash_set(size_type __n, const hasher& __hf)
134169691Skan      : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
13597403Sobrien
136169691Skan      hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
137169691Skan	       const allocator_type& __a = allocator_type())
138169691Skan      : _M_ht(__n, __hf, __eql, __a) {}
13997403Sobrien
140169691Skan      template<class _InputIterator>
141169691Skan        hash_set(_InputIterator __f, _InputIterator __l)
142169691Skan	: _M_ht(100, hasher(), key_equal(), allocator_type())
143169691Skan        { _M_ht.insert_unique(__f, __l); }
14497403Sobrien
145169691Skan      template<class _InputIterator>
146169691Skan        hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
147169691Skan	: _M_ht(__n, hasher(), key_equal(), allocator_type())
148169691Skan        { _M_ht.insert_unique(__f, __l); }
14997403Sobrien
150169691Skan      template<class _InputIterator>
151169691Skan        hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
152169691Skan		 const hasher& __hf)
153169691Skan	: _M_ht(__n, __hf, key_equal(), allocator_type())
154169691Skan        { _M_ht.insert_unique(__f, __l); }
15597403Sobrien
156169691Skan      template<class _InputIterator>
157169691Skan        hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
158169691Skan		 const hasher& __hf, const key_equal& __eql,
159169691Skan		 const allocator_type& __a = allocator_type())
160169691Skan	: _M_ht(__n, __hf, __eql, __a)
161169691Skan        { _M_ht.insert_unique(__f, __l); }
16297403Sobrien
163169691Skan    public:
164169691Skan      size_type
165169691Skan      size() const
166169691Skan      { return _M_ht.size(); }
16797403Sobrien
168169691Skan      size_type
169169691Skan      max_size() const
170169691Skan      { return _M_ht.max_size(); }
171169691Skan      
172169691Skan      bool
173169691Skan      empty() const
174169691Skan      { return _M_ht.empty(); }
175169691Skan      
176169691Skan      void
177169691Skan      swap(hash_set& __hs)
178169691Skan      { _M_ht.swap(__hs._M_ht); }
179169691Skan
180169691Skan      template<class _Val, class _HF, class _EqK, class _Al>
181169691Skan        friend bool
182169691Skan        operator==(const hash_set<_Val, _HF, _EqK, _Al>&,
183169691Skan		   const hash_set<_Val, _HF, _EqK, _Al>&);
184169691Skan
185169691Skan      iterator
186169691Skan      begin() const
187169691Skan      { return _M_ht.begin(); }
188169691Skan      
189169691Skan      iterator
190169691Skan      end() const
191169691Skan      { return _M_ht.end(); }
192169691Skan
193169691Skan    public:
194169691Skan      pair<iterator, bool>
195169691Skan      insert(const value_type& __obj)
196169691Skan      {
197169691Skan	pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique(__obj);
198169691Skan	return pair<iterator,bool>(__p.first, __p.second);
199169691Skan      }
200169691Skan
201169691Skan      template<class _InputIterator>
202169691Skan        void
203169691Skan        insert(_InputIterator __f, _InputIterator __l)
204169691Skan        { _M_ht.insert_unique(__f, __l); }
205169691Skan
206169691Skan      pair<iterator, bool>
207169691Skan      insert_noresize(const value_type& __obj)
208169691Skan      {
209169691Skan	pair<typename _Ht::iterator, bool> __p
210169691Skan	  = _M_ht.insert_unique_noresize(__obj);
211169691Skan	return pair<iterator, bool>(__p.first, __p.second);
212169691Skan      }
213169691Skan
214169691Skan      iterator
215169691Skan      find(const key_type& __key) const
216169691Skan      { return _M_ht.find(__key); }
217169691Skan
218169691Skan      size_type
219169691Skan      count(const key_type& __key) const
220169691Skan      { return _M_ht.count(__key); }
221169691Skan
222169691Skan      pair<iterator, iterator>
223169691Skan      equal_range(const key_type& __key) const
224169691Skan      { return _M_ht.equal_range(__key); }
225169691Skan
226169691Skan      size_type
227169691Skan      erase(const key_type& __key)
228169691Skan      {return _M_ht.erase(__key); }
229169691Skan      
230169691Skan      void
231169691Skan      erase(iterator __it)
232169691Skan      { _M_ht.erase(__it); }
233169691Skan      
234169691Skan      void
235169691Skan      erase(iterator __f, iterator __l)
236169691Skan      { _M_ht.erase(__f, __l); }
237169691Skan      
238169691Skan      void
239169691Skan      clear()
240169691Skan      { _M_ht.clear(); }
241169691Skan
242169691Skan    public:
243169691Skan      void
244169691Skan      resize(size_type __hint)
245169691Skan      { _M_ht.resize(__hint); }
246169691Skan      
247169691Skan      size_type
248169691Skan      bucket_count() const
249169691Skan      { return _M_ht.bucket_count(); }
250169691Skan      
251169691Skan      size_type
252169691Skan      max_bucket_count() const
253169691Skan      { return _M_ht.max_bucket_count(); }
254169691Skan      
255169691Skan      size_type
256169691Skan      elems_in_bucket(size_type __n) const
257169691Skan      { return _M_ht.elems_in_bucket(__n); }
258169691Skan    };
259169691Skan
260169691Skan  template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
261169691Skan    inline bool
262169691Skan    operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
263169691Skan	       const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
264169691Skan    { return __hs1._M_ht == __hs2._M_ht; }
265169691Skan
266169691Skan  template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
267169691Skan    inline bool
268169691Skan    operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
269169691Skan	       const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
270169691Skan    { return !(__hs1 == __hs2); }
271169691Skan
272169691Skan  template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
273169691Skan    inline void
274169691Skan    swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
275169691Skan	 hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
276169691Skan    { __hs1.swap(__hs2); }
277169691Skan
278169691Skan
279169691Skan  /**
280169691Skan   *  This is an SGI extension.
281169691Skan   *  @ingroup SGIextensions
282169691Skan   *  @doctodo
283169691Skan   */
284169691Skan  template<class _Value,
285169691Skan	   class _HashFcn = hash<_Value>,
286169691Skan	   class _EqualKey = equal_to<_Value>,
287169691Skan	   class _Alloc = allocator<_Value> >
288169691Skan    class hash_multiset
28997403Sobrien    {
290169691Skan      // concept requirements
291169691Skan      __glibcxx_class_requires(_Value, _SGIAssignableConcept)
292169691Skan      __glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
293169691Skan      __glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
29497403Sobrien
295169691Skan    private:
296169691Skan      typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
297169691Skan			_EqualKey, _Alloc> _Ht;
298169691Skan      _Ht _M_ht;
29997403Sobrien
300169691Skan    public:
301169691Skan      typedef typename _Ht::key_type key_type;
302169691Skan      typedef typename _Ht::value_type value_type;
303169691Skan      typedef typename _Ht::hasher hasher;
304169691Skan      typedef typename _Ht::key_equal key_equal;
305169691Skan      
306169691Skan      typedef typename _Ht::size_type size_type;
307169691Skan      typedef typename _Ht::difference_type difference_type;
308169691Skan      typedef typename _Alloc::pointer pointer;
309169691Skan      typedef typename _Alloc::const_pointer const_pointer;
310169691Skan      typedef typename _Alloc::reference reference;
311169691Skan      typedef typename _Alloc::const_reference const_reference;
312132720Skan
313169691Skan      typedef typename _Ht::const_iterator iterator;
314169691Skan      typedef typename _Ht::const_iterator const_iterator;
315169691Skan      
316169691Skan      typedef typename _Ht::allocator_type allocator_type;
317169691Skan      
318169691Skan      hasher
319169691Skan      hash_funct() const
320169691Skan      { return _M_ht.hash_funct(); }
321169691Skan      
322169691Skan      key_equal
323169691Skan      key_eq() const
324169691Skan      { return _M_ht.key_eq(); }
325169691Skan      
326169691Skan      allocator_type
327169691Skan      get_allocator() const
328169691Skan      { return _M_ht.get_allocator(); }
32997403Sobrien
330169691Skan    public:
331169691Skan      hash_multiset()
332169691Skan      : _M_ht(100, hasher(), key_equal(), allocator_type()) {}
33397403Sobrien
334169691Skan      explicit
335169691Skan      hash_multiset(size_type __n)
336169691Skan      : _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
33797403Sobrien
338169691Skan      hash_multiset(size_type __n, const hasher& __hf)
339169691Skan      : _M_ht(__n, __hf, key_equal(), allocator_type()) {}
340169691Skan      
341169691Skan      hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
342169691Skan		    const allocator_type& __a = allocator_type())
343169691Skan      : _M_ht(__n, __hf, __eql, __a) {}
34497403Sobrien
345169691Skan      template<class _InputIterator>
346169691Skan        hash_multiset(_InputIterator __f, _InputIterator __l)
347169691Skan	: _M_ht(100, hasher(), key_equal(), allocator_type())
348169691Skan        { _M_ht.insert_equal(__f, __l); }
34997403Sobrien
350169691Skan      template<class _InputIterator>
351169691Skan        hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
352169691Skan	: _M_ht(__n, hasher(), key_equal(), allocator_type())
353169691Skan        { _M_ht.insert_equal(__f, __l); }
35497403Sobrien
355169691Skan      template<class _InputIterator>
356169691Skan        hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
357169691Skan		      const hasher& __hf)
358169691Skan	: _M_ht(__n, __hf, key_equal(), allocator_type())
359169691Skan        { _M_ht.insert_equal(__f, __l); }
36097403Sobrien
361169691Skan      template<class _InputIterator>
362169691Skan        hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
363169691Skan		      const hasher& __hf, const key_equal& __eql,
364169691Skan		      const allocator_type& __a = allocator_type())
365169691Skan	: _M_ht(__n, __hf, __eql, __a)
366169691Skan        { _M_ht.insert_equal(__f, __l); }
36797403Sobrien
368169691Skan    public:
369169691Skan      size_type
370169691Skan      size() const
371169691Skan      { return _M_ht.size(); }
37297403Sobrien
373169691Skan      size_type
374169691Skan      max_size() const
375169691Skan      { return _M_ht.max_size(); }
37697403Sobrien
377169691Skan      bool
378169691Skan      empty() const
379169691Skan      { return _M_ht.empty(); }
38097403Sobrien
381169691Skan      void
382169691Skan      swap(hash_multiset& hs)
383169691Skan      { _M_ht.swap(hs._M_ht); }
38497403Sobrien
385169691Skan      template<class _Val, class _HF, class _EqK, class _Al>
386169691Skan        friend bool
387169691Skan        operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&,
388169691Skan		   const hash_multiset<_Val, _HF, _EqK, _Al>&);
38997403Sobrien
390169691Skan      iterator
391169691Skan      begin() const
392169691Skan      { return _M_ht.begin(); }
393169691Skan      
394169691Skan      iterator
395169691Skan      end() const
396169691Skan      { return _M_ht.end(); }
39797403Sobrien
398169691Skan    public:
399169691Skan      iterator
400169691Skan      insert(const value_type& __obj)
401169691Skan      { return _M_ht.insert_equal(__obj); }
402169691Skan  
403169691Skan      template<class _InputIterator>
404169691Skan        void
405169691Skan        insert(_InputIterator __f, _InputIterator __l)
406169691Skan        { _M_ht.insert_equal(__f,__l); }
407169691Skan  
408169691Skan      iterator
409169691Skan      insert_noresize(const value_type& __obj)
410169691Skan      { return _M_ht.insert_equal_noresize(__obj); }
41197403Sobrien
412169691Skan      iterator
413169691Skan      find(const key_type& __key) const
414169691Skan      { return _M_ht.find(__key); }
41597403Sobrien
416169691Skan      size_type
417169691Skan      count(const key_type& __key) const
418169691Skan      { return _M_ht.count(__key); }
41997403Sobrien
420169691Skan      pair<iterator, iterator>
421169691Skan      equal_range(const key_type& __key) const
422169691Skan      { return _M_ht.equal_range(__key); }
42397403Sobrien
424169691Skan      size_type
425169691Skan      erase(const key_type& __key)
426169691Skan      { return _M_ht.erase(__key); }
427169691Skan  
428169691Skan      void
429169691Skan      erase(iterator __it)
430169691Skan      { _M_ht.erase(__it); }
431169691Skan  
432169691Skan      void
433169691Skan      erase(iterator __f, iterator __l)
434169691Skan      { _M_ht.erase(__f, __l); }
435169691Skan  
436169691Skan      void
437169691Skan      clear()
438169691Skan      { _M_ht.clear(); }
43997403Sobrien
440169691Skan    public:
441169691Skan      void
442169691Skan      resize(size_type __hint)
443169691Skan      { _M_ht.resize(__hint); }
444169691Skan  
445169691Skan      size_type
446169691Skan      bucket_count() const
447169691Skan      { return _M_ht.bucket_count(); }
44897403Sobrien
449169691Skan      size_type
450169691Skan      max_bucket_count() const
451169691Skan      { return _M_ht.max_bucket_count(); }
45297403Sobrien
453169691Skan      size_type
454169691Skan      elems_in_bucket(size_type __n) const
455169691Skan      { return _M_ht.elems_in_bucket(__n); }
456169691Skan    };
45797403Sobrien
458169691Skan  template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
459169691Skan    inline bool
460169691Skan    operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
461169691Skan	       const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
462169691Skan    { return __hs1._M_ht == __hs2._M_ht; }
46397403Sobrien
464169691Skan  template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
465169691Skan    inline bool
466169691Skan    operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
467169691Skan	       const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
468169691Skan    { return !(__hs1 == __hs2); }
46997403Sobrien
470169691Skan  template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
471169691Skan    inline void
472169691Skan    swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
473169691Skan	 hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
474169691Skan    { __hs1.swap(__hs2); }
475132720Skan
476169691Skan_GLIBCXX_END_NESTED_NAMESPACE
47797403Sobrien
478169691Skan#ifdef _GLIBCXX_DEBUG
479169691Skan# include <debug/hash_set>
480169691Skan#endif
48197403Sobrien
482169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
48397403Sobrien
484169691Skan  // Specialization of insert_iterator so that it will work for hash_set
485169691Skan  // and hash_multiset.
486169691Skan  template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
487169691Skan    class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn,
488169691Skan					      _EqualKey, _Alloc> >
489169691Skan    {
490169691Skan    protected:
491169691Skan      typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc>
492169691Skan        _Container;
493169691Skan      _Container* container;
49497403Sobrien
495169691Skan    public:
496169691Skan      typedef _Container          container_type;
497169691Skan      typedef output_iterator_tag iterator_category;
498169691Skan      typedef void                value_type;
499169691Skan      typedef void                difference_type;
500169691Skan      typedef void                pointer;
501169691Skan      typedef void                reference;
50297403Sobrien
503169691Skan      insert_iterator(_Container& __x)
504169691Skan      : container(&__x) {}
505169691Skan      
506169691Skan      insert_iterator(_Container& __x, typename _Container::iterator)
507169691Skan      : container(&__x) {}
50897403Sobrien
509169691Skan      insert_iterator<_Container>&
510169691Skan      operator=(const typename _Container::value_type& __value)
511169691Skan      {
512169691Skan	container->insert(__value);
513169691Skan	return *this;
514169691Skan      }
51597403Sobrien
516169691Skan      insert_iterator<_Container>&
517169691Skan      operator*()
518169691Skan      { return *this; }
519169691Skan      
520169691Skan      insert_iterator<_Container>&
521169691Skan      operator++()
522169691Skan      { return *this; }
523169691Skan      
524169691Skan      insert_iterator<_Container>&
525169691Skan      operator++(int)
526169691Skan      { return *this; }
527169691Skan    };
52897403Sobrien
529169691Skan  template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
530169691Skan    class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn,
531169691Skan						   _EqualKey, _Alloc> >
532169691Skan    {
533169691Skan    protected:
534169691Skan      typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>
535169691Skan        _Container;
536169691Skan      _Container* container;
537169691Skan      typename _Container::iterator iter;
53897403Sobrien
539169691Skan    public:
540169691Skan      typedef _Container          container_type;
541169691Skan      typedef output_iterator_tag iterator_category;
542169691Skan      typedef void                value_type;
543169691Skan      typedef void                difference_type;
544169691Skan      typedef void                pointer;
545169691Skan      typedef void                reference;
546169691Skan      
547169691Skan      insert_iterator(_Container& __x)
548169691Skan      : container(&__x) {}
549169691Skan      
550169691Skan      insert_iterator(_Container& __x, typename _Container::iterator)
551169691Skan      : container(&__x) {}
55297403Sobrien
553169691Skan      insert_iterator<_Container>&
554169691Skan      operator=(const typename _Container::value_type& __value)
555169691Skan      {
556169691Skan	container->insert(__value);
557169691Skan	return *this;
558169691Skan      }
55997403Sobrien
560169691Skan      insert_iterator<_Container>&
561169691Skan      operator*()
562169691Skan      { return *this; }
56397403Sobrien
564169691Skan      insert_iterator<_Container>&
565169691Skan      operator++()
566169691Skan      { return *this; }
567169691Skan
568169691Skan      insert_iterator<_Container>&
569169691Skan      operator++(int) { return *this; }
570169691Skan    };
571169691Skan
572169691Skan_GLIBCXX_END_NAMESPACE
573169691Skan
574132720Skan#endif
575