Nugget
fixed_hash_set.h
1 // Copyright (c) Electronic Arts Inc. All rights reserved.
4 
6 // This file implements a hash_set which uses a fixed size memory pool for
7 // its buckets and nodes.
9 
10 
11 #ifndef EASTL_FIXED_HASH_SET_H
12 #define EASTL_FIXED_HASH_SET_H
13 
14 
15 #include <EASTL/hash_set.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 
26 namespace eastl
27 {
34  #ifndef EASTL_FIXED_HASH_SET_DEFAULT_NAME
35  #define EASTL_FIXED_HASH_SET_DEFAULT_NAME EASTL_DEFAULT_NAME_PREFIX " fixed_hash_set" // Unless the user overrides something, this is "EASTL fixed_hash_set".
36  #endif
37 
38  #ifndef EASTL_FIXED_HASH_MULTISET_DEFAULT_NAME
39  #define EASTL_FIXED_HASH_MULTISET_DEFAULT_NAME EASTL_DEFAULT_NAME_PREFIX " fixed_hash_multiset" // Unless the user overrides something, this is "EASTL fixed_hash_multiset".
40  #endif
41 
42 
46  #ifndef EASTL_FIXED_HASH_SET_DEFAULT_ALLOCATOR
47  #define EASTL_FIXED_HASH_SET_DEFAULT_ALLOCATOR overflow_allocator_type(EASTL_FIXED_HASH_SET_DEFAULT_NAME)
48  #endif
49 
50  #ifndef EASTL_FIXED_HASH_MULTISET_DEFAULT_ALLOCATOR
51  #define EASTL_FIXED_HASH_MULTISET_DEFAULT_ALLOCATOR overflow_allocator_type(EASTL_FIXED_HASH_MULTISET_DEFAULT_NAME)
52  #endif
53 
54 
55 
69  template <typename Value, size_t nodeCount, size_t bucketCount = nodeCount + 1, bool bEnableOverflow = true,
70  typename Hash = eastl::hash<Value>, typename Predicate = eastl::equal_to<Value>, bool bCacheHashCode = false, typename OverflowAllocator = EASTLAllocatorType>
71  class fixed_hash_set : public hash_set<Value,
72  Hash,
73  Predicate,
74  fixed_hashtable_allocator<
75  bucketCount + 1,
76  sizeof(typename hash_set<Value, Hash, Predicate, OverflowAllocator, bCacheHashCode>::node_type),
77  nodeCount,
78  EASTL_ALIGN_OF(typename hash_set<Value, Hash, Predicate, OverflowAllocator, bCacheHashCode>::node_type),
79  0,
80  bEnableOverflow,
81  OverflowAllocator>,
82  bCacheHashCode>
83  {
84  public:
85  typedef fixed_hashtable_allocator<bucketCount + 1, sizeof(typename hash_set<Value, Hash, Predicate,
86  OverflowAllocator, bCacheHashCode>::node_type), nodeCount,
87  EASTL_ALIGN_OF(typename hash_set<Value, Hash, Predicate, OverflowAllocator, bCacheHashCode>::node_type),
88  0, bEnableOverflow, OverflowAllocator> fixed_allocator_type;
89  typedef typename fixed_allocator_type::overflow_allocator_type overflow_allocator_type;
90  typedef fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator> this_type;
91  typedef hash_set<Value, Hash, Predicate, fixed_allocator_type, bCacheHashCode> base_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 
100  protected:
101  node_type** mBucketBuffer[bucketCount + 1]; // '+1' because the hash table needs a null terminating bucket.
102  char mNodeBuffer[fixed_allocator_type::kBufferSize]; // kBufferSize will take into account alignment requirements.
103 
104  public:
105  explicit fixed_hash_set(const overflow_allocator_type& overflowAllocator);
106 
107  explicit fixed_hash_set(const Hash& hashFunction = Hash(),
108  const Predicate& predicate = Predicate());
109 
110  fixed_hash_set(const Hash& hashFunction,
111  const Predicate& predicate,
112  const overflow_allocator_type& overflowAllocator);
113 
114  template <typename InputIterator>
115  fixed_hash_set(InputIterator first, InputIterator last,
116  const Hash& hashFunction = Hash(),
117  const Predicate& predicate = Predicate());
118 
119  fixed_hash_set(const this_type& x);
120  fixed_hash_set(this_type&& x);
121  fixed_hash_set(this_type&& x, const overflow_allocator_type& overflowAllocator);
122 
123  fixed_hash_set(std::initializer_list<value_type> ilist, const overflow_allocator_type& overflowAllocator = EASTL_FIXED_HASH_SET_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  }; // fixed_hash_set
139 
140 
141 
142 
143 
144 
157  template <typename Value, size_t nodeCount, size_t bucketCount = nodeCount + 1, bool bEnableOverflow = true,
158  typename Hash = eastl::hash<Value>, typename Predicate = eastl::equal_to<Value>, bool bCacheHashCode = false, typename OverflowAllocator = EASTLAllocatorType>
159  class fixed_hash_multiset : public hash_multiset<Value,
160  Hash,
161  Predicate,
162  fixed_hashtable_allocator<
163  bucketCount + 1,
164  sizeof(typename hash_multiset<Value, Hash, Predicate, OverflowAllocator, bCacheHashCode>::node_type),
165  nodeCount,
166  EASTL_ALIGN_OF(typename hash_multiset<Value, Hash, Predicate, OverflowAllocator, bCacheHashCode>::node_type),
167  0,
168  bEnableOverflow,
169  OverflowAllocator>,
170  bCacheHashCode>
171  {
172  public:
173  typedef fixed_hashtable_allocator<bucketCount + 1, sizeof(typename hash_multiset<Value, Hash, Predicate,
174  OverflowAllocator, bCacheHashCode>::node_type), nodeCount, EASTL_ALIGN_OF(typename hash_multiset<Value, Hash, Predicate,
175  OverflowAllocator, bCacheHashCode>::node_type), 0,
176  bEnableOverflow, OverflowAllocator> fixed_allocator_type;
177  typedef typename fixed_allocator_type::overflow_allocator_type overflow_allocator_type;
178  typedef hash_multiset<Value, Hash, Predicate, fixed_allocator_type, bCacheHashCode> base_type;
179  typedef fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator> this_type;
180  typedef typename base_type::value_type value_type;
181  typedef typename base_type::node_type node_type;
182  typedef typename base_type::size_type size_type;
183 
184  enum { kMaxSize = nodeCount };
185 
186  using base_type::mAllocator;
187 
188  protected:
189  node_type** mBucketBuffer[bucketCount + 1]; // '+1' because the hash table needs a null terminating bucket.
190  char mNodeBuffer[fixed_allocator_type::kBufferSize]; // kBufferSize will take into account alignment requirements.
191 
192  public:
193  explicit fixed_hash_multiset(const overflow_allocator_type& overflowAllocator);
194 
195  explicit fixed_hash_multiset(const Hash& hashFunction = Hash(),
196  const Predicate& predicate = Predicate());
197 
198  fixed_hash_multiset(const Hash& hashFunction,
199  const Predicate& predicate,
200  const overflow_allocator_type& overflowAllocator);
201 
202  template <typename InputIterator>
203  fixed_hash_multiset(InputIterator first, InputIterator last,
204  const Hash& hashFunction = Hash(),
205  const Predicate& predicate = Predicate());
206 
207  fixed_hash_multiset(const this_type& x);
208  fixed_hash_multiset(this_type&& x);
209  fixed_hash_multiset(this_type&& x, const overflow_allocator_type& overflowAllocator);
210  fixed_hash_multiset(std::initializer_list<value_type> ilist, const overflow_allocator_type& overflowAllocator = EASTL_FIXED_HASH_MULTISET_DEFAULT_ALLOCATOR);
211 
212  this_type& operator=(const this_type& x);
213  this_type& operator=(std::initializer_list<value_type> ilist);
214  this_type& operator=(this_type&& x);
215 
216  void swap(this_type& x);
217 
218  void reset_lose_memory(); // This is a unilateral reset to an initially empty state. No destructors are called, no deallocation occurs.
219 
220  size_type max_size() const;
221 
222  const overflow_allocator_type& get_overflow_allocator() const EA_NOEXCEPT;
223  overflow_allocator_type& get_overflow_allocator() EA_NOEXCEPT;
224  void set_overflow_allocator(const overflow_allocator_type& allocator);
225  }; // fixed_hash_multiset
226 
227 
228 
229 
230 
232  // fixed_hash_set
234 
235  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
236  inline fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
237  fixed_hash_set(const overflow_allocator_type& overflowAllocator)
238  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount),
239  Hash(), Predicate(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
240  {
241  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
242 
243  if (!bEnableOverflow)
244  {
245  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
246  }
247 
248  #if EASTL_NAME_ENABLED
249  mAllocator.set_name(EASTL_FIXED_HASH_SET_DEFAULT_NAME);
250  #endif
251 
252  mAllocator.reset(mNodeBuffer);
253  }
254 
255 
256  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
257  inline fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
258  fixed_hash_set(const Hash& hashFunction,
259  const Predicate& predicate)
260  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount),
261  hashFunction, predicate, fixed_allocator_type(NULL, mBucketBuffer))
262  {
263  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
264 
265  if(!bEnableOverflow)
266  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
267 
268  #if EASTL_NAME_ENABLED
269  mAllocator.set_name(EASTL_FIXED_HASH_SET_DEFAULT_NAME);
270  #endif
271 
272  mAllocator.reset(mNodeBuffer);
273  }
274 
275 
276  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
277  inline fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
278  fixed_hash_set(const Hash& hashFunction,
279  const Predicate& predicate,
280  const overflow_allocator_type& overflowAllocator)
281  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount),
282  hashFunction, predicate, fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
283  {
284  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
285 
286  if (!bEnableOverflow)
287  {
288  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
289  }
290 
291  #if EASTL_NAME_ENABLED
292  mAllocator.set_name(EASTL_FIXED_HASH_SET_DEFAULT_NAME);
293  #endif
294 
295  mAllocator.reset(mNodeBuffer);
296  }
297 
298 
299  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
300  template <typename InputIterator>
301  fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
302  fixed_hash_set(InputIterator first, InputIterator last,
303  const Hash& hashFunction,
304  const Predicate& predicate)
305  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), hashFunction,
306  predicate, fixed_allocator_type(NULL, mBucketBuffer))
307  {
308  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
309 
310  if(!bEnableOverflow)
311  {
312  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
313  }
314 
315  #if EASTL_NAME_ENABLED
316  mAllocator.set_name(EASTL_FIXED_HASH_SET_DEFAULT_NAME);
317  #endif
318 
319  mAllocator.reset(mNodeBuffer);
320  base_type::insert(first, last);
321  }
322 
323 
324  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
325  inline fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
326  fixed_hash_set(const this_type& x)
327  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
328  x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer))
329  {
330  mAllocator.copy_overflow_allocator(x.mAllocator);
331 
332  #if EASTL_NAME_ENABLED
333  mAllocator.set_name(x.mAllocator.get_name());
334  #endif
335 
336  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
337 
338  if(!bEnableOverflow)
339  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
340 
341  mAllocator.reset(mNodeBuffer);
342  base_type::insert(x.begin(), x.end());
343  }
344 
345 
346  template <typename Key, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
347  inline fixed_hash_set<Key, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::fixed_hash_set(this_type&& x)
348  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
349  x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer))
350  {
351  // 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.
352  mAllocator.copy_overflow_allocator(x.mAllocator);
353 
354  #if EASTL_NAME_ENABLED
355  mAllocator.set_name(x.mAllocator.get_name());
356  #endif
357 
358  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
359 
360  if(!bEnableOverflow)
361  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
362 
363  mAllocator.reset(mNodeBuffer);
364  base_type::insert(x.begin(), x.end());
365  }
366 
367 
368  template <typename Key, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
369  inline fixed_hash_set<Key, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::fixed_hash_set(this_type&& x, const overflow_allocator_type& overflowAllocator)
370  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount),
371  x.hash_function(), x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
372  {
373  // 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.
374  mAllocator.copy_overflow_allocator(x.mAllocator);
375 
376  #if EASTL_NAME_ENABLED
377  mAllocator.set_name(x.mAllocator.get_name());
378  #endif
379 
380  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
381 
382  if(!bEnableOverflow)
383  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
384 
385  mAllocator.reset(mNodeBuffer);
386  base_type::insert(x.begin(), x.end());
387  }
388 
389 
390  template <typename Key, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
391  inline fixed_hash_set<Key, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
392  fixed_hash_set(std::initializer_list<value_type> ilist, const overflow_allocator_type& overflowAllocator)
393  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), Hash(),
394  Predicate(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
395  {
396  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
397 
398  if(!bEnableOverflow)
399  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
400 
401  #if EASTL_NAME_ENABLED
402  mAllocator.set_name(EASTL_FIXED_HASH_SET_DEFAULT_NAME);
403  #endif
404 
405  mAllocator.reset(mNodeBuffer);
406  base_type::insert(ilist.begin(), ilist.end());
407  }
408 
409 
410  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
411  typename fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::this_type&
412  fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::operator=(const this_type& x)
413  {
414  base_type::operator=(x);
415  return *this;
416  }
417 
418 
419  template <typename Key, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
420  inline typename fixed_hash_set<Key, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::this_type&
421  fixed_hash_set<Key, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::operator=(this_type&& x)
422  {
423  operator=(x);
424  return *this;
425  }
426 
427 
428  template <typename Key, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
429  inline typename fixed_hash_set<Key, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::this_type&
430  fixed_hash_set<Key, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::operator=(std::initializer_list<value_type> ilist)
431  {
432  base_type::clear();
433  base_type::insert(ilist.begin(), ilist.end());
434  return *this;
435  }
436 
437 
438  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
439  inline void fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
440  swap(this_type& x)
441  {
442  // We must do a brute-force swap, because fixed containers cannot share memory allocations.
443  // Note that we create a temp value on the stack. This approach may fail if the size of the
444  // container is too large. We have a rule against allocating memory from the heap, and so
445  // if the user wants to swap two large objects of this class, the user will currently need
446  // to implement it manually. To consider: add code to allocate a temporary buffer if the
447  // size of the container is too large for the stack.
448  EASTL_ASSERT(sizeof(x) < EASTL_MAX_STACK_USAGE); // It is dangerous to try to create objects that are too big for the stack.
449 
450  const this_type temp(*this); // Can't call eastl::swap because that would
451  *this = x; // itself call this member swap function.
452  x = temp;
453  }
454 
455 
456  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
457  void fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
458  reset_lose_memory()
459  {
460  base_type::reset_lose_memory();
461  base_type::get_allocator().reset(mNodeBuffer);
462  }
463 
464 
465  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
466  inline typename fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::size_type
467  fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::max_size() const
468  {
469  return kMaxSize;
470  }
471 
472 
473  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
474  inline const typename fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::overflow_allocator_type&
475  fixed_hash_set<Value, 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 Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
482  inline typename fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::overflow_allocator_type&
483  fixed_hash_set<Value, 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 Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
490  inline void fixed_hash_set<Value, 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 
497  // global operators
499 
500  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode>
501  inline void swap(fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode>& a,
502  fixed_hash_set<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode>& b)
503  {
504  a.swap(b);
505  }
506 
507 
508 
509 
511  // fixed_hash_multiset
513 
514  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
515  inline fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
516  fixed_hash_multiset(const overflow_allocator_type& overflowAllocator)
517  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), Hash(),
518  Predicate(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
519  {
520  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
521 
522  if(!bEnableOverflow)
523  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
524 
525  #if EASTL_NAME_ENABLED
526  mAllocator.set_name(EASTL_FIXED_HASH_MULTISET_DEFAULT_NAME);
527  #endif
528 
529  mAllocator.reset(mNodeBuffer);
530  }
531 
532 
533  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
534  inline fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
535  fixed_hash_multiset(const Hash& hashFunction,
536  const Predicate& predicate)
537  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), hashFunction,
538  predicate, fixed_allocator_type(NULL, mBucketBuffer))
539  {
540  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
541 
542  if(!bEnableOverflow)
543  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
544 
545  #if EASTL_NAME_ENABLED
546  mAllocator.set_name(EASTL_FIXED_HASH_MULTISET_DEFAULT_NAME);
547  #endif
548 
549  mAllocator.reset(mNodeBuffer);
550  }
551 
552 
553  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
554  inline fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
555  fixed_hash_multiset(const Hash& hashFunction,
556  const Predicate& predicate,
557  const overflow_allocator_type& overflowAllocator)
558  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), hashFunction,
559  predicate, fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
560  {
561  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
562 
563  if(!bEnableOverflow)
564  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
565 
566  #if EASTL_NAME_ENABLED
567  mAllocator.set_name(EASTL_FIXED_HASH_MULTISET_DEFAULT_NAME);
568  #endif
569 
570  mAllocator.reset(mNodeBuffer);
571  }
572 
573 
574  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
575  template <typename InputIterator>
576  inline fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
577  fixed_hash_multiset(InputIterator first, InputIterator last,
578  const Hash& hashFunction,
579  const Predicate& predicate)
580  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), hashFunction,
581  predicate, fixed_allocator_type(NULL, mBucketBuffer))
582  {
583  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
584 
585  if(!bEnableOverflow)
586  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
587 
588  #if EASTL_NAME_ENABLED
589  mAllocator.set_name(EASTL_FIXED_HASH_MULTISET_DEFAULT_NAME);
590  #endif
591 
592  mAllocator.reset(mNodeBuffer);
593  base_type::insert(first, last);
594  }
595 
596 
597  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
598  inline fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
599  fixed_hash_multiset(const this_type& x)
600  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
601  x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer))
602  {
603  mAllocator.copy_overflow_allocator(x.mAllocator);
604 
605  #if EASTL_NAME_ENABLED
606  mAllocator.set_name(x.mAllocator.get_name());
607  #endif
608 
609  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
610 
611  if(!bEnableOverflow)
612  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
613 
614  mAllocator.reset(mNodeBuffer);
615  base_type::insert(x.begin(), x.end());
616  }
617 
618 
619  template <typename Key, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
620  inline fixed_hash_multiset<Key, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::fixed_hash_multiset(this_type&& x)
621  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
622  x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer))
623  {
624  // 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.
625  mAllocator.copy_overflow_allocator(x.mAllocator);
626 
627  #if EASTL_NAME_ENABLED
628  mAllocator.set_name(x.mAllocator.get_name());
629  #endif
630 
631  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
632 
633  if(!bEnableOverflow)
634  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
635 
636  mAllocator.reset(mNodeBuffer);
637  base_type::insert(x.begin(), x.end());
638  }
639 
640 
641  template <typename Key, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
642  inline fixed_hash_multiset<Key, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::fixed_hash_multiset(this_type&& x, const overflow_allocator_type& overflowAllocator)
643  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount),
644  x.hash_function(), x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
645  {
646  // 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.
647  mAllocator.copy_overflow_allocator(x.mAllocator);
648 
649  #if EASTL_NAME_ENABLED
650  mAllocator.set_name(x.mAllocator.get_name());
651  #endif
652 
653  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
654 
655  if(!bEnableOverflow)
656  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
657 
658  mAllocator.reset(mNodeBuffer);
659  base_type::insert(x.begin(), x.end());
660  }
661 
662 
663  template <typename Key, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
664  inline fixed_hash_multiset<Key, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
665  fixed_hash_multiset(std::initializer_list<value_type> ilist, const overflow_allocator_type& overflowAllocator)
666  : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), Hash(),
667  Predicate(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
668  {
669  EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
670 
671  if(!bEnableOverflow)
672  base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
673 
674  #if EASTL_NAME_ENABLED
675  mAllocator.set_name(EASTL_FIXED_HASH_MULTISET_DEFAULT_NAME);
676  #endif
677 
678  mAllocator.reset(mNodeBuffer);
679  base_type::insert(ilist.begin(), ilist.end());
680  }
681 
682 
683  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
684  inline typename fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::this_type&
685  fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::operator=(const this_type& x)
686  {
687  base_type::operator=(x);
688  return *this;
689  }
690 
691 
692  template <typename Key, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
693  inline typename fixed_hash_multiset<Key, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::this_type&
694  fixed_hash_multiset<Key, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::operator=(this_type&& x)
695  {
696  base_type::operator=(x);
697  return *this;
698  }
699 
700 
701  template <typename Key, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
702  inline typename fixed_hash_multiset<Key, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::this_type&
703  fixed_hash_multiset<Key, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::operator=(std::initializer_list<value_type> ilist)
704  {
705  base_type::clear();
706  base_type::insert(ilist.begin(), ilist.end());
707  return *this;
708  }
709 
710 
711  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
712  inline void fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
713  swap(this_type& x)
714  {
715  // Fixed containers use a special swap that can deal with excessively large buffers.
716  eastl::fixed_swap(*this, x);
717  }
718 
719 
720  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
721  inline void fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
722  reset_lose_memory()
723  {
724  base_type::reset_lose_memory();
725  base_type::get_allocator().reset(mNodeBuffer);
726  }
727 
728 
729  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
730  inline typename fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::size_type
731  fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::max_size() const
732  {
733  return kMaxSize;
734  }
735 
736 
737  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
738  inline const typename fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::overflow_allocator_type&
739  fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::get_overflow_allocator() const EA_NOEXCEPT
740  {
741  return mAllocator.get_overflow_allocator();
742  }
743 
744 
745  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
746  inline typename fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::overflow_allocator_type&
747  fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::get_overflow_allocator() EA_NOEXCEPT
748  {
749  return mAllocator.get_overflow_allocator();
750  }
751 
752 
753  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode, typename OverflowAllocator>
754  inline void fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode, OverflowAllocator>::
755  set_overflow_allocator(const overflow_allocator_type& allocator)
756  {
757  mAllocator.set_overflow_allocator(allocator);
758  }
759 
760 
762  // global operators
764 
765  template <typename Value, size_t nodeCount, size_t bucketCount, bool bEnableOverflow, typename Hash, typename Predicate, bool bCacheHashCode>
766  inline void swap(fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode>& a,
767  fixed_hash_multiset<Value, nodeCount, bucketCount, bEnableOverflow, Hash, Predicate, bCacheHashCode>& b)
768  {
769  // Fixed containers use a special swap that can deal with excessively large buffers.
770  eastl::fixed_swap(a, b);
771  }
772 
773 
774 } // namespace eastl
775 
776 EA_RESTORE_VC_WARNING()
777 
778 #endif // Header include guard
779 
780 
781 
782 
783 
784 
785 
786 
787 
788 
789 
790 
Definition: initializer_list.h:38
EA Standard Template Library.
Definition: algorithm.h:288
Definition: functional.h:139
Definition: functional.h:1015