fixed: compile issue
[opensg.git] / Source / External / google / dense_hash_map
blob02e427f19c163ecd993572bf24e74abf7a77bbfc
1 // Copyright (c) 2005, Google Inc.
2 // All rights reserved.
3 // 
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 // 
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 // 
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 // ----
31 // Author: Craig Silverstein
33 // This is just a very thin wrapper over densehashtable.h, just
34 // like sgi stl's stl_hash_map is a very thin wrapper over 
35 // stl_hashtable.  The major thing we define is operator[], because
36 // we have a concept of a data_type which stl_hashtable doesn't
37 // (it only has a key and a value).
39 // NOTE: this is exactly like sparse_hash_map.h, with the word
40 // "sparse" replaced by "dense", except for the addition of
41 // set_empty_key().
43 //   YOU MUST CALL SET_EMPTY_KEY() IMMEDIATELY AFTER CONSTRUCTION.
45 // Otherwise your program will die in mysterious ways.
47 // In other respects, we adhere mostly to the STL semantics for
48 // hash-map.  One important exception is that insert() invalidates
49 // iterators entirely.  On the plus side, though, erase() doesn't
50 // invalidate iterators at all, or even change the ordering of elements.
52 // Here are a few "power user" tips:
54 //    1) set_deleted_key():
55 //         If you want to use erase() you must call set_deleted_key(),
56 //         in addition to set_empty_key(), after construction.
58 //    2) resize(0):
59 //         When an item is deleted, its memory isn't freed right
60 //         away.  This allows you to iterate over a hashtable,
61 //         and call erase(), without invalidating the iterator.
62 //         To force the memory to be freed, call resize(0).
64 // Guide to what kind of hash_map to use:
65 //   (1) dense_hash_map: fastest, uses the most memory
66 //   (2) sparse_hash_map: slowest, uses the least memory
67 //   (3) hash_map (STL): in the middle
68 // Typically I use sparse_hash_map when I care about space and/or when
69 // I need to save the hashtable on disk.  I use hash_map otherwise.  I
70 // don't personally use dense_hash_map ever; the only use of
71 // dense_hash_map I know of is to work around malloc() bugs in some
72 // systems (dense_hash_map has a particularly simple allocation scheme).
74 // - dense_hash_map has, typically, a factor of 2 memory overhead (if your
75 //   data takes up X bytes, the hash_map uses X more bytes in overhead).
76 // - sparse_hash_map has about 2 bits overhead per entry.
77 // - sparse_hash_map can be 3-7 times slower than the others for lookup and,
78 //   especially, inserts.  See time_hash_map.cc for details.
80 // See /usr/(local/)?doc/sparsehash-0.1/dense_hash_map.html
81 // for information about how to use this class.
83 #ifndef _DENSE_HASH_MAP_H_
84 #define _DENSE_HASH_MAP_H_
86 // !!! DR changed some <google/...> to "..." due to include path problems...
87 #include "sparsehash/google_config.h"
88 #include <stdio.h>                   // for FILE * in read()/write()
89 #include <algorithm>                 // for the default template args
90 #include <functional>                // for equal_to
91 #include <memory>                    // for alloc<>
92 #include "sparsehash/hash_fun.h"
93 #include "sparsehash/densehashtable.h"
96 // Lots of STLs don't support type traits, so we might just do without.
97 // We also have a guard to make sure we don't include this code twice:
98 // once for sparse_hash_map and once for dense_hash_map.
99 #if defined(UNDERSTANDS_TYPE_TRAITS) && !defined(_ANDED_TRAITS_)
100 #define _ANDED_TRAITS_
102 #if defined HAVE_TYPE_TRAITS
103 #include <type_traits.h>
104 #elif defined HAVE_BITS_TYPE_TRAITS
105 #include <bits/type_traits.h>
106 #endif
108 // We need to let the densetable know that our pair<Key,Data> is
109 // a Plain Old Data type if both the Key and Data are.
110 template <class Key, class T>       
111 struct __and_trait {                             // by default x & y == false
112     typedef __false_type tp;
115 template <> struct __and_trait<__true_type, __true_type> {   // but true & true == true
116     typedef __true_type tp;
119 #define AND_(trait)                                                     \
120    typedef typename __and_trait<typename __type_traits<Key>::trait,     \
121                                 typename __type_traits< T >::trait>::tp \
122    trait
124 template <class Key, class T>
125 struct __type_traits< STL_NAMESPACE::pair<const Key, T> > {
126   AND_(has_trivial_default_constructor);
127   AND_(has_trivial_copy_constructor);
128   AND_(has_trivial_assignment_operator);
129   AND_(has_trivial_destructor);
130   AND_(is_POD_type);
133 #undef AND_
135 #endif   /* #defined UNDERSTANDS_TYPE_TRAITS && _ANDED_TRAITS_ */
137 _START_GOOGLE_NAMESPACE_
139 using STL_NAMESPACE::pair;
141 template <class Key, class T,
142           class HashFcn = HASH_NAMESPACE::hash<Key>,
143           class EqualKey = STL_NAMESPACE::equal_to<Key>,
144           class Alloc = STL_NAMESPACE::allocator<T> >
145 class dense_hash_map {
147  private:
148   // Apparently select1st is not stl-standard, so we define our own
149   struct SelectKey {
150     const Key& operator()(const pair<const Key, T>& p) const { 
151       return p.first;
152     }
153   };
155   // The actual data
156   typedef dense_hashtable<pair<const Key, T>, Key, HashFcn,
157                           SelectKey, EqualKey, Alloc> ht;
158   ht rep;
160  public:
161   typedef typename ht::key_type key_type;
162   typedef T data_type;
163   typedef T mapped_type;
164   typedef typename ht::value_type value_type;
165   typedef typename ht::hasher hasher;
166   typedef typename ht::key_equal key_equal;
168   typedef typename ht::size_type size_type;
169   typedef typename ht::difference_type difference_type;
170   typedef typename ht::pointer pointer;
171   typedef typename ht::const_pointer const_pointer;
172   typedef typename ht::reference reference;
173   typedef typename ht::const_reference const_reference;
175   typedef typename ht::iterator iterator;
176   typedef typename ht::const_iterator const_iterator;
178   // Iterator functions
179   iterator begin()                    { return rep.begin(); }
180   iterator end()                      { return rep.end(); }
181   const_iterator begin() const        { return rep.begin(); }
182   const_iterator end() const          { return rep.end(); }
185   // Accessor functions
186   hasher hash_funct() const { return rep.hash_funct(); }
187   key_equal key_eq() const  { return rep.key_eq(); }
190   // Constructors
191   explicit dense_hash_map(size_type n = 0,
192                           const hasher& hf = hasher(),
193                           const key_equal& eql = key_equal()) 
194     : rep(n, hf, eql) { }
195   
196   template <class InputIterator>
197   dense_hash_map(InputIterator f, InputIterator l,
198                  size_type n = 0,
199                  const hasher& hf = hasher(),
200                  const key_equal& eql = key_equal()) {
201     rep.insert(f, l);
202   }
203   // We use the default copy constructor
204   // We use the default operator=()
205   // We use the default destructor
207   void clear()                        { rep.clear(); }
208   void swap(dense_hash_map& hs)       { rep.swap(hs.rep); }
211   // Functions concerning size
212   size_type size() const              { return rep.size(); }
213   size_type max_size() const          { return rep.max_size(); }
214   bool empty() const                  { return rep.empty(); }
215   size_type bucket_count() const      { return rep.bucket_count(); }
216   size_type max_bucket_count() const  { return rep.max_bucket_count(); }
218   void resize(size_type hint)         { rep.resize(hint); }
221   // Lookup routines
222   iterator find(const key_type& key)                 { return rep.find(key); }
223   const_iterator find(const key_type& key) const     { return rep.find(key); }
225   data_type& operator[](const key_type& key) {       // This is our value-add!
226     return (*((rep.insert(value_type(key, data_type()))).first)).second;
227   }
229   size_type count(const key_type& key) const         { return rep.count(key); }
230   
231   pair<iterator, iterator> equal_range(const key_type& key) {
232     return rep.equal_range(key);
233   }
234   pair<const_iterator, const_iterator> equal_range(const key_type& key) const {
235     return rep.equal_range(key);
236   }
237   
238   // Insertion routines
239   pair<iterator, bool> insert(const value_type& obj) { return rep.insert(obj); }
240   template <class InputIterator>
241   void insert(InputIterator f, InputIterator l)      { rep.insert(f, l); }
242   void insert(const_iterator f, const_iterator l)    { rep.insert(f, l); }
243   // required for std::insert_iterator; the passed-in iterator is ignored
244   iterator insert(iterator, const value_type& obj)   { return insert(obj).first; }
247   // Deletion and empty routines
248   // THESE ARE NON-STANDARD!  I make you specify an "impossible" key
249   // value to identify deleted and empty buckets.  You can change the
250   // deleted key as time goes on, or get rid of it entirely to be insert-only.
251   void set_empty_key(const key_type& key)   {           // YOU MUST CALL THIS!
252     rep.set_empty_key(key);
253   }
254   void set_deleted_key(const key_type& key)   {
255     rep.set_deleted_key(key);
256   }
257   void clear_deleted_key()                    { rep.clear_deleted_key(); }
259   // These are standard
260   size_type erase(const key_type& key)               { return rep.erase(key); }
261   void erase(iterator it)                            { rep.erase(it); }
262   void erase(iterator f, iterator l)                 { rep.erase(f, l); }
265   // Comparison
266   bool operator==(const dense_hash_map& hs) const    { return rep == hs.rep; }
267   bool operator!=(const dense_hash_map& hs) const    { return rep != hs.rep; }
270   // I/O -- this is an add-on for writing metainformation to disk
271   bool write_metadata(FILE *fp)       { return rep.write_metadata(fp); }
272   bool read_metadata(FILE *fp)        { return rep.read_metadata(fp); }
273   bool write_nopointer_data(FILE *fp) { return rep.write_nopointer_data(fp); }
274   bool read_nopointer_data(FILE *fp)  { return rep.read_nopointer_data(fp); }
277 // We need a global swap as well
278 template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
279 inline void swap(dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1,
280                  dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2) {
281   hm1.swap(hm2);
284 _END_GOOGLE_NAMESPACE_
286 #endif /* _DENSE_HASH_MAP_H_ */