Nugget
fixed_hash_map.h
1 // Copyright (c) Electronic Arts Inc. All rights reserved.
4 
6 // This file implements a hash_map and hash_multimap which use a fixed size
7 // memory pool for its buckets and nodes.
9 
10 
11 #ifndef EASTL_FIXED_HASH_MAP_H
12 #define EASTL_FIXED_HASH_MAP_H
13 
14 
15 #include <EASTL/hash_map.h>
16 #include <EASTL/internal/fixed_pool.h>
17 
18 EA_DISABLE_VC_WARNING(4127) // Conditional expression is constant
19 
20 #if defined(EA_PRAGMA_ONCE_SUPPORTED)
21  #pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result.
22 #endif
23 
24 
25 namespace eastl
26 {
33  #ifndef EASTL_FIXED_HASH_MAP_DEFAULT_NAME
34  #define EASTL_FIXED_HASH_MAP_DEFAULT_NAME EASTL_DEFAULT_NAME_PREFIX " fixed_hash_map" // Unless the user overrides something, this is "EASTL fixed_hash_map".
35  #endif
36 
37  #ifndef EASTL_FIXED_HASH_MULTIMAP_DEFAULT_NAME
38  #define EASTL_FIXED_HASH_MULTIMAP_DEFAULT_NAME EASTL_DEFAULT_NAME_PREFIX " fixed_hash_multimap" // Unless the user overrides something, this is "EASTL fixed_hash_multimap".
39  #endif
40 
41 
45  #ifndef EASTL_FIXED_HASH_MAP_DEFAULT_ALLOCATOR
46  #define EASTL_FIXED_HASH_MAP_DEFAULT_ALLOCATOR overflow_allocator_type(EASTL_FIXED_HASH_MAP_DEFAULT_NAME)
47  #endif
48 
49  #ifndef EASTL_FIXED_HASH_MULTIMAP_DEFAULT_ALLOCATOR
50  #define EASTL_FIXED_HASH_MULTIMAP_DEFAULT_ALLOCATOR overflow_allocator_type(EASTL_FIXED_HASH_MULTIMAP_DEFAULT_NAME)
51  #endif
52 
53 
54 
69  template <typename Key, typename T, size_t nodeCount, size_t bucketCount = nodeCount + 1, bool bEnableOverflow = true,
70  typename Hash = eastl::hash<Key>, typename Predicate = eastl::equal_to<Key>, bool bCacheHashCode = false, typename OverflowAllocator = EASTLAllocatorType>
71  class fixed_hash_map : public hash_map<Key,
72  T,
73  Hash,
74  Predicate,
75  fixed_hashtable_allocator<
76  bucketCount + 1,
77  sizeof(typename hash_map<Key, T, Hash, Predicate, OverflowAllocator, bCacheHashCode>::node_type),
78  nodeCount,
79  EASTL_ALIGN_OF(eastl::pair<Key, T>),
80  0,
81  bEnableOverflow,
82  OverflowAllocator>,
83  bCacheHashCode>
84  {
85  public:
86  typedef fixed_hashtable_allocator<bucketCount + 1, sizeof(typename hash_map<Key, T, Hash, Predicate,
87  OverflowAllocator, bCacheHashCode>::node_type), nodeCount, EASTL_ALIGN_OF(eastl::pair<Key, T>), 0,
88  bEnableOverflow, OverflowAllocator> fixed_allocator_type;
89  typedef typename fixed_allocator_type::overflow_allocator_type overflow_allocator_type;
90  typedef hash_map<Key, T, Hash, Predicate, fixed_allocator_type, bCacheHashCode> base_type;
91  typedef fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator> this_type;
92  typedef typename base_type::value_type value_type;
93  typedef typename base_type::node_type node_type;
94  typedef typename base_type::size_type size_type;
95 
96  enum { kMaxSize = nodeCount };
97 
98  using base_type::mAllocator;
99  using base_type::clear;
100 
101  protected:
102  node_type** mBucketBuffer[bucketCount + 1]; // '+1' because the hash table needs a null terminating bucket.
103  char mNodeBuffer[fixed_allocator_type::kBufferSize]; // kBufferSize will take into account alignment requirements.
104 
105  public:
106  explicit fixed_hash_map(const overflow_allocator_type& overflowAllocator);
107 
108  explicit fixed_hash_map(const Hash& hashFunction = Hash(),
109  const Predicate& predicate = Predicate());
110 
111  fixed_hash_map(const Hash& hashFunction,
112  const Predicate& predicate,
113  const overflow_allocator_type& overflowAllocator);
114 
115  template <typename InputIterator>
116  fixed_hash_map(InputIterator first, InputIterator last,
117  const Hash& hashFunction = Hash(),
118  const Predicate& predicate = Predicate());
119 
120  fixed_hash_map(const this_type& x);
121  fixed_hash_map(this_type&& x);
122  fixed_hash_map(this_type&& x, const overflow_allocator_type& overflowAllocator);
123  fixed_hash_map(std::initializer_list<value_type> ilist, const overflow_allocator_type& overflowAllocator = EASTL_FIXED_HASH_MAP_DEFAULT_ALLOCATOR);
124 
125  this_type& operator=(const this_type& x);
126  this_type& operator=(std::initializer_list<value_type> ilist);
127  this_type& operator=(this_type&& x);
128 
129  void swap(this_type& x);
130 
131  void reset_lose_memory(); // This is a unilateral reset to an initially empty state. No destructors are called, no deallocation occurs.
132 
133  size_type max_size() const;
134 
135  const overflow_allocator_type& get_overflow_allocator() const EA_NOEXCEPT;
136  overflow_allocator_type& get_overflow_allocator() EA_NOEXCEPT;
137  void set_overflow_allocator(const overflow_allocator_type& allocator);
138 
139  void clear(bool clearBuckets);
140  }; // fixed_hash_map
141 
142 
143 
144 
145 
160  template <typename Key, typename T, size_t nodeCount, size_t bucketCount = nodeCount + 1, bool bEnableOverflow = true,
161  typename Hash = eastl::hash<Key>, typename Predicate = eastl::equal_to<Key>, bool bCacheHashCode = false, typename OverflowAllocator = EASTLAllocatorType>
162  class fixed_hash_multimap : public hash_multimap<Key,
163  T,
164  Hash,
165  Predicate,
166  fixed_hashtable_allocator<
167  bucketCount + 1,
168  sizeof(typename hash_multimap<Key, T, Hash, Predicate, OverflowAllocator, bCacheHashCode>::node_type),
169  nodeCount,
170  EASTL_ALIGN_OF(eastl::pair<Key, T>),
171  0,
172  bEnableOverflow,
173  OverflowAllocator>,
174  bCacheHashCode>
175  {
176  public:
177  typedef fixed_hashtable_allocator<bucketCount + 1, sizeof(typename hash_multimap<Key, T, Hash, Predicate,
178  OverflowAllocator, bCacheHashCode>::node_type), nodeCount, EASTL_ALIGN_OF(eastl::pair<Key, T>), 0,
179  bEnableOverflow, OverflowAllocator> fixed_allocator_type;
180  typedef typename fixed_allocator_type::overflow_allocator_type overflow_allocator_type;
181  typedef hash_multimap<Key, T, Hash, Predicate, fixed_allocator_type, bCacheHashCode> base_type;
182  typedef fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator> this_type;
183  typedef typename base_type::value_type value_type;
184  typedef typename base_type::node_type node_type;
185  typedef typename base_type::size_type size_type;
186 
187  enum { kMaxSize = nodeCount };
188 
189  using base_type::mAllocator;
190  using base_type::clear;
191 
192  protected:
193  node_type** mBucketBuffer[bucketCount + 1]; // '+1' because the hash table needs a null terminating bucket.
194  char mNodeBuffer[fixed_allocator_type::kBufferSize]; // kBufferSize will take into account alignment requirements.
195 
196  public:
197  explicit fixed_hash_multimap(const overflow_allocator_type& overflowAllocator);
198 
199  explicit fixed_hash_multimap(const Hash& hashFunction = Hash(),
200  const Predicate& predicate = Predicate());
201 
202  fixed_hash_multimap(const Hash& hashFunction,
203  const Predicate& predicate,
204  const overflow_allocator_type& overflowAllocator);
205 
206  template <typename InputIterator>
207  fixed_hash_multimap(InputIterator first, InputIterator last,
208  const Hash& hashFunction = Hash(),
209  const Predicate& predicate = Predicate());
210 
211  fixed_hash_multimap(const this_type& x);
212  fixed_hash_multimap(this_type&& x);
213  fixed_hash_multimap(this_type&& x, const overflow_allocator_type& overflowAllocator);
214  fixed_hash_multimap(std::initializer_list<value_type> ilist, const overflow_allocator_type& overflowAllocator = EASTL_FIXED_HASH_MULTIMAP_DEFAULT_ALLOCATOR);
215 
216  this_type& operator=(const this_type& x);
217  this_type& operator=(std::initializer_list<value_type> ilist);
218  this_type& operator=(this_type&& x);
219 
220  void swap(this_type& x);
221 
222  void reset_lose_memory(); // This is a unilateral reset to an initially empty state. No destructors are called, no deallocation occurs.
223 
224  size_type max_size() const;
225 
226  const overflow_allocator_type& get_overflow_allocator() const EA_NOEXCEPT;
227  overflow_allocator_type& get_overflow_allocator() EA_NOEXCEPT;
228  void set_overflow_allocator(const overflow_allocator_type& allocator);
229 
230  void clear(bool clearBuckets);
231  }; // fixed_hash_multimap
232 
233 
234 
235 
236 
237 
239  // fixed_hash_map
241 
242  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
243  inline fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
244  fixed_hash_map(const overflow_allocator_type& overflowAllocator)
245  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), Hash(),
246  Predicate(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
247  {
248  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
249 
250  if(!bEnableOverflow)
251  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
252 
253  #if EASTL_NAME_ENABLED
254  mAllocator.set_name(EASTL_FIXED_HASH_MAP_DEFAULT_NAME);
255  #endif
256 
257  mAllocator.reset(mNodeBuffer);
258  }
259 
260 
261  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
262  inline fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
263  fixed_hash_map(const Hash& hashFunction,
264  const Predicate& predicate)
265  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), hashFunction,
266  predicate, fixed_allocator_type(NULL, mBucketBuffer))
267  {
268  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
269 
270  if (!bEnableOverflow)
271  {
272  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
273  }
274 
275  #if EASTL_NAME_ENABLED
276  mAllocator.set_name(EASTL_FIXED_HASH_MAP_DEFAULT_NAME);
277  #endif
278 
279  mAllocator.reset(mNodeBuffer);
280  }
281 
282 
283  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
284  inline fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
285  fixed_hash_map(const Hash& hashFunction,
286  const Predicate& predicate,
287  const overflow_allocator_type& overflowAllocator)
288  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), hashFunction,
289  predicate, fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
290  {
291  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
292 
293  if (!bEnableOverflow)
294  {
295  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
296  }
297 
298  #if EASTL_NAME_ENABLED
299  mAllocator.set_name(EASTL_FIXED_HASH_MAP_DEFAULT_NAME);
300  #endif
301 
302  mAllocator.reset(mNodeBuffer);
303  }
304 
305 
306  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
307  template <typename InputIterator>
308  fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
309  fixed_hash_map(InputIterator first, InputIterator last,
310  const Hash& hashFunction,
311  const Predicate& predicate)
312  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), hashFunction,
313  predicate, fixed_allocator_type(NULL, mBucketBuffer))
314  {
315  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
316 
317  if(!bEnableOverflow)
318  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
319 
320  #if EASTL_NAME_ENABLED
321  mAllocator.set_name(EASTL_FIXED_HASH_MAP_DEFAULT_NAME);
322  #endif
323 
324  mAllocator.reset(mNodeBuffer);
325  base_type::insert(first, last);
326  }
327 
328 
329  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
330  inline fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
331  fixed_hash_map(const this_type& x)
332  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
333  x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer))
334  {
335  mAllocator.copy_overflow_allocator(x.mAllocator);
336 
337  #if EASTL_NAME_ENABLED
338  mAllocator.set_name(x.mAllocator.get_name());
339  #endif
340 
341  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
342 
343  if(!bEnableOverflow)
344  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
345 
346  mAllocator.reset(mNodeBuffer);
347  base_type::insert(x.begin(), x.end());
348  }
349 
350 
351  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
352  inline fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
353  fixed_hash_map(this_type&& x)
354  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
355  x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer))
356  {
357  // This implementation is the same as above. If we could rely on using C++11 delegating constructor support then we could just call that here.
358  mAllocator.copy_overflow_allocator(x.mAllocator);
359 
360  #if EASTL_NAME_ENABLED
361  mAllocator.set_name(x.mAllocator.get_name());
362  #endif
363 
364  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
365 
366  if(!bEnableOverflow)
367  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
368 
369  mAllocator.reset(mNodeBuffer);
370  base_type::insert(x.begin(), x.end());
371  }
372 
373 
374  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
375  inline fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
376  fixed_hash_map(this_type&& x, const overflow_allocator_type& overflowAllocator)
377  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
378  x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
379  {
380  // This implementation is the same as above. If we could rely on using C++11 delegating constructor support then we could just call that here.
381  mAllocator.copy_overflow_allocator(x.mAllocator);
382 
383  #if EASTL_NAME_ENABLED
384  mAllocator.set_name(x.mAllocator.get_name());
385  #endif
386 
387  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
388 
389  if(!bEnableOverflow)
390  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
391 
392  mAllocator.reset(mNodeBuffer);
393  base_type::insert(x.begin(), x.end());
394  }
395 
396 
397  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
398  inline fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
399  fixed_hash_map(std::initializer_list<value_type> ilist, const overflow_allocator_type& overflowAllocator)
400  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), Hash(),
401  Predicate(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
402  {
403  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
404 
405  if(!bEnableOverflow)
406  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
407 
408  #if EASTL_NAME_ENABLED
409  mAllocator.set_name(EASTL_FIXED_HASH_MAP_DEFAULT_NAME);
410  #endif
411 
412  mAllocator.reset(mNodeBuffer);
413  base_type::insert(ilist.begin(), ilist.end());
414  }
415 
416 
417  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
418  inline typename fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::this_type&
419  fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::operator=(const this_type& x)
420  {
421  base_type::operator=(x);
422  return *this;
423  }
424 
425 
426  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
427  inline typename fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::this_type&
428  fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::operator=(this_type&& x)
429  {
430  base_type::operator=(x);
431  return *this;
432  }
433 
434 
435  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
436  inline typename fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::this_type&
437  fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::operator=(std::initializer_list<value_type> ilist)
438  {
439  base_type::clear();
440  base_type::insert(ilist.begin(), ilist.end());
441  return *this;
442  }
443 
444 
445  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
446  inline void fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
447  swap(this_type& x)
448  {
449  // Fixed containers use a special swap that can deal with excessively large buffers.
450  eastl::fixed_swap(*this, x);
451  }
452 
453 
454  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
455  inline void fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
456  reset_lose_memory()
457  {
458  base_type::mnBucketCount = (size_type)base_type::mRehashPolicy.GetPrevBucketCount((uint32_t)bucketCount);
459  base_type::mnElementCount = 0;
460  base_type::mRehashPolicy.mnNextResize = 0;
461  base_type::get_allocator().reset(mNodeBuffer);
462  }
463 
464 
465  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
466  inline typename fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::size_type
467  fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::max_size() const
468  {
469  return kMaxSize;
470  }
471 
472 
473  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
474  inline const typename fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::overflow_allocator_type&
475  fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::get_overflow_allocator() const EA_NOEXCEPT
476  {
477  return mAllocator.get_overflow_allocator();
478  }
479 
480 
481  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
482  inline typename fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::overflow_allocator_type&
483  fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::get_overflow_allocator() EA_NOEXCEPT
484  {
485  return mAllocator.get_overflow_allocator();
486  }
487 
488 
489  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
490  inline void fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
491  set_overflow_allocator(const overflow_allocator_type& allocator)
492  {
493  mAllocator.set_overflow_allocator(allocator);
494  }
495 
496 
497  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
498  inline void fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
499  clear(bool clearBuckets)
500  {
501  base_type::DoFreeNodes(base_type::mpBucketArray, base_type::mnBucketCount);
502  if(clearBuckets)
503  {
504  base_type::DoFreeBuckets(base_type::mpBucketArray, base_type::mnBucketCount);
505  reset_lose_memory();
506  }
507  base_type::mpBucketArray = (node_type**)mBucketBuffer;
508  base_type::mnElementCount = 0;
509  }
510 
511 
513  // global operators
515 
516  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode>
517  inline void swap(fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode>& a,
518  fixed_hash_map<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode>& b)
519  {
520  // Fixed containers use a special swap that can deal with excessively large buffers.
521  eastl::fixed_swap(a, b);
522  }
523 
524 
525 
526 
528  // fixed_hash_multimap
530 
531  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
532  inline fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
533  fixed_hash_multimap(const overflow_allocator_type& overflowAllocator)
534  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), Hash(),
535  Predicate(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
536  {
537  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
538 
539  if (!bEnableOverflow)
540  {
541  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
542  }
543 
544  #if EASTL_NAME_ENABLED
545  mAllocator.set_name(EASTL_FIXED_HASH_MULTIMAP_DEFAULT_NAME);
546  #endif
547 
548  mAllocator.reset(mNodeBuffer);
549  }
550 
551 
552  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
553  inline fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
554  fixed_hash_multimap(const Hash& hashFunction,
555  const Predicate& predicate)
556  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), hashFunction,
557  predicate, fixed_allocator_type(NULL, mBucketBuffer))
558  {
559  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
560 
561  if(!bEnableOverflow)
562  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
563 
564  #if EASTL_NAME_ENABLED
565  mAllocator.set_name(EASTL_FIXED_HASH_MULTIMAP_DEFAULT_NAME);
566  #endif
567 
568  mAllocator.reset(mNodeBuffer);
569  }
570 
571 
572  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
573  inline fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
574  fixed_hash_multimap(const Hash& hashFunction,
575  const Predicate& predicate,
576  const overflow_allocator_type& overflowAllocator)
577  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), hashFunction,
578  predicate, fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
579  {
580  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
581 
582  if(!bEnableOverflow)
583  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
584 
585  #if EASTL_NAME_ENABLED
586  mAllocator.set_name(EASTL_FIXED_HASH_MULTIMAP_DEFAULT_NAME);
587  #endif
588 
589  mAllocator.reset(mNodeBuffer);
590  }
591 
592 
593  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
594  template <typename InputIterator>
595  fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
596  fixed_hash_multimap(InputIterator first, InputIterator last,
597  const Hash& hashFunction,
598  const Predicate& predicate)
599  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), hashFunction,
600  predicate, fixed_allocator_type(NULL, mBucketBuffer))
601  {
602  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
603 
604  if(!bEnableOverflow)
605  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
606 
607  #if EASTL_NAME_ENABLED
608  mAllocator.set_name(EASTL_FIXED_HASH_MULTIMAP_DEFAULT_NAME);
609  #endif
610 
611  mAllocator.reset(mNodeBuffer);
612  base_type::insert(first, last);
613  }
614 
615 
616  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
617  inline fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
618  fixed_hash_multimap(const this_type& x)
619  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
620  x.equal_function(),fixed_allocator_type(NULL, mBucketBuffer))
621  {
622  mAllocator.copy_overflow_allocator(x.mAllocator);
623 
624  #if EASTL_NAME_ENABLED
625  mAllocator.set_name(x.mAllocator.get_name());
626  #endif
627 
628  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
629 
630  if(!bEnableOverflow)
631  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
632 
633  mAllocator.reset(mNodeBuffer);
634  base_type::insert(x.begin(), x.end());
635  }
636 
637 
638  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
639  inline fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
640  fixed_hash_multimap(this_type&& x)
641  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
642  x.equal_function(),fixed_allocator_type(NULL, mBucketBuffer))
643  {
644  // This implementation is the same as above. If we could rely on using C++11 delegating constructor support then we could just call that here.
645  mAllocator.copy_overflow_allocator(x.mAllocator);
646 
647  #if EASTL_NAME_ENABLED
648  mAllocator.set_name(x.mAllocator.get_name());
649  #endif
650 
651  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
652 
653  if(!bEnableOverflow)
654  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
655 
656  mAllocator.reset(mNodeBuffer);
657  base_type::insert(x.begin(), x.end());
658  }
659 
660 
661  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
662  inline fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
663  fixed_hash_multimap(this_type&& x, const overflow_allocator_type& overflowAllocator)
664  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
665  x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
666  {
667  // This implementation is the same as above. If we could rely on using C++11 delegating constructor support then we could just call that here.
668  mAllocator.copy_overflow_allocator(x.mAllocator);
669 
670  #if EASTL_NAME_ENABLED
671  mAllocator.set_name(x.mAllocator.get_name());
672  #endif
673 
674  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
675 
676  if(!bEnableOverflow)
677  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
678 
679  mAllocator.reset(mNodeBuffer);
680  base_type::insert(x.begin(), x.end());
681  }
682 
683 
684  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
685  inline fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
686  fixed_hash_multimap(std::initializer_list<value_type> ilist, const overflow_allocator_type& overflowAllocator)
687  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), Hash(),
688  Predicate(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
689  {
690  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
691 
692  if(!bEnableOverflow)
693  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
694 
695  #if EASTL_NAME_ENABLED
696  mAllocator.set_name(EASTL_FIXED_HASH_MULTIMAP_DEFAULT_NAME);
697  #endif
698 
699  mAllocator.reset(mNodeBuffer);
700  base_type::insert(ilist.begin(), ilist.end());
701  }
702 
703 
704  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
705  inline typename fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::this_type&
706  fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::operator=(const this_type& x)
707  {
708  base_type::operator=(x);
709  return *this;
710  }
711 
712 
713  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
714  inline typename fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::this_type&
715  fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::operator=(this_type&& x)
716  {
717  base_type::operator=(x);
718  return *this;
719  }
720 
721 
722  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
723  inline typename fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::this_type&
724  fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::operator=(std::initializer_list<value_type> ilist)
725  {
726  base_type::clear();
727  base_type::insert(ilist.begin(), ilist.end());
728  return *this;
729  }
730 
731 
732  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
733  inline void fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
734  swap(this_type& x)
735  {
736  // Fixed containers use a special swap that can deal with excessively large buffers.
737  eastl::fixed_swap(*this, x);
738  }
739 
740 
741  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
742  inline void fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
743  reset_lose_memory()
744  {
745  base_type::mnBucketCount = (size_type)base_type::mRehashPolicy.GetPrevBucketCount((uint32_t)bucketCount);
746  base_type::mnElementCount = 0;
747  base_type::mRehashPolicy.mnNextResize = 0;
748  base_type::get_allocator().reset(mNodeBuffer);
749  }
750 
751 
752  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
753  inline typename fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::size_type
754  fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::max_size() const
755  {
756  return kMaxSize;
757  }
758 
759 
760  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
761  inline const typename fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::overflow_allocator_type&
762  fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::get_overflow_allocator() const EA_NOEXCEPT
763  {
764  return mAllocator.get_overflow_allocator();
765  }
766 
767 
768  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
769  inline typename fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::overflow_allocator_type&
770  fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::get_overflow_allocator() EA_NOEXCEPT
771  {
772  return mAllocator.get_overflow_allocator();
773  }
774 
775 
776  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
777  inline void fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::set_overflow_allocator(const overflow_allocator_type& allocator)
778  {
779  mAllocator.set_overflow_allocator(allocator);
780  }
781 
782 
783  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
784  inline void fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
785  clear(bool clearBuckets)
786  {
787  base_type::DoFreeNodes(base_type::mpBucketArray, base_type::mnBucketCount);
788  if(clearBuckets)
789  {
790  base_type::DoFreeBuckets(base_type::mpBucketArray, base_type::mnBucketCount);
791  reset_lose_memory();
792  }
793  base_type::mpBucketArray = (node_type**)mBucketBuffer;
794  base_type::mnElementCount = 0;
795  }
796 
797 
799  // global operators
801 
802  template <typename Key, typename T, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode>
803  inline void swap(fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode>& a,
804  fixed_hash_multimap<Key, T, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode>& b)
805  {
806  // Fixed containers use a special swap that can deal with excessively large buffers.
807  eastl::fixed_swap(a, b);
808  }
809 
810 
811 
812 } // namespace eastl
813 
814 EA_RESTORE_VC_WARNING()
815 
816 #endif // Header include guard
817 
818 
819 
820 
821 
822 
823 
824 
825 
826 
827 
828 
Definition: initializer_list.h:38
EA Standard Template Library.
Definition: algorithm.h:288
Definition: functional.h:139
Definition: functional.h:1015
Definition: utility.h:371