BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_hashtable_cpp03.h
Go to the documentation of this file.
1/// @file bslstl_hashtable_cpp03.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_hashtable_cpp03.h -*-C++-*-
8
9// Automatically generated file. **DO NOT EDIT**
10
11#ifndef INCLUDED_BSLSTL_HASHTABLE_CPP03
12#define INCLUDED_BSLSTL_HASHTABLE_CPP03
13
14/// @defgroup bslstl_hashtable_cpp03 bslstl_hashtable_cpp03
15/// @brief Provide C++03 implementation for bslstl_hashtable.h
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_hashtable_cpp03
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_hashtable_cpp03-purpose"> Purpose</a>
25/// * <a href="#bslstl_hashtable_cpp03-classes"> Classes </a>
26/// * <a href="#bslstl_hashtable_cpp03-description"> Description </a>
27///
28/// # Purpose {#bslstl_hashtable_cpp03-purpose}
29/// Provide C++03 implementation for bslstl_hashtable.h
30///
31/// # Classes {#bslstl_hashtable_cpp03-classes}
32/// See bslstl_hashtable.h for list of classes
33///
34/// @see bslstl_hashtable
35///
36/// # Description {#bslstl_hashtable_cpp03-description}
37/// This component is the C++03 translation of a C++11 component,
38/// generated by the 'sim_cpp11_features.pl' program. If the original header
39/// contains any specially delimited regions of C++11 code, then this generated
40/// file contains the C++03 equivalent, i.e., with variadic templates expanded
41/// and rvalue-references replaced by 'bslmf::MovableRef' objects. The header
42/// code in this file is designed to be '#include'd into the original header
43/// when compiling with a C++03 compiler. If there are no specially delimited
44/// regions of C++11 code, then this header contains no code and is not
45/// '#include'd in the original header.
46///
47/// Generated on Thu Mar 5 22:50:49 2026
48/// Command line: sim_cpp11_features.pl bslstl_hashtable.h
49/// @}
50/** @} */
51/** @} */
52
53/** @addtogroup bsl
54 * @{
55 */
56/** @addtogroup bslstl
57 * @{
58 */
59/** @addtogroup bslstl_hashtable_cpp03
60 * @{
61 */
62
63#ifdef COMPILING_BSLSTL_HASHTABLE_H
64
65
66
67namespace bslstl {
68
69template <class KEY_CONFIG,
70 class HASHER,
71 class COMPARATOR,
73class HashTable;
74
75template <class FACTORY>
76class HashTable_ArrayProctor;
77
78template <class FACTORY>
79class HashTable_NodeProctor;
80
81template <class FUNCTOR>
82class HashTable_ComparatorWrapper;
83
84template <class FUNCTOR>
85class HashTable_ComparatorWrapper<const FUNCTOR>;
86
87template <class FUNCTOR>
88class HashTable_ComparatorWrapper<FUNCTOR &>;
89
90template <class FUNCTOR>
91class HashTable_HashWrapper;
92
93template <class FUNCTOR>
94class HashTable_HashWrapper<const FUNCTOR>;
95
96template <class FUNCTOR>
97class HashTable_HashWrapper<FUNCTOR &>;
98
99struct HashTable_ImpDetails;
100struct HashTable_Util;
101
102 // ======================
103 // class CallableVariable
104 // ======================
105
106/// This metafunction returns a `type` that is an alias for `CALLABLE`
107/// unless that is a function type, in which case it is an alias for
108/// `CALLABLE &`. This should be used to declare variables of an arbitrary
109/// callable type, typically a template type parameter, that may turn out to be a function type.
110///
111/// \note Note that this metafunction is necessary as the C++
112/// language does not allow variables of function type, nor may functions
113/// return a function type.
114///
115/// See @ref bslstl_hashtable_cpp03
116template <class CALLABLE>
117struct CallableVariable {
118
119 // TYPES
120 typedef typename bsl::conditional<
123 CALLABLE>::type type;
124};
125
126 // ===========================
127 // class HashTable_HashWrapper
128 // ===========================
129
130/// This class provides a wrapper around a functor satisfying the `Hash`
131/// requirements (@ref bslstl_hash ) such that the function call operator is
132/// always declared as `const` qualified.
133///
134/// TBD Provide an optimization for the case of an empty base functor, where
135/// we can safely const_cast want calling the base class operator.
136///
137///
138/// \note Note that we would only one class, not two, with C++11 variadic
139/// templates and perfect forwarding, and we could also easily detect
140/// whether or not `FUNCTOR` provided a const-qualified `operator()`.
141///
142/// See @ref bslstl_hashtable_cpp03
143template <class FUNCTOR>
144class HashTable_HashWrapper {
145
146 private:
147 mutable FUNCTOR d_functor;
148
149 public:
150 // CREATORS
151
152 /// Create a `HashTable_HashWrapper` object wrapping a `FUNCTOR` that
153 /// has its default value.
155
156 /// Create a `HashTable_HashWrapper` object wrapping a `FUNCTOR` that is
157 /// a copy of the specified `fn`.
158 explicit HashTable_HashWrapper(const FUNCTOR& fn);
159
160 // MANIPULATORS
161
162 /// Exchange the value of this object with the specified `other` object.
163 void swap(HashTable_HashWrapper &other);
164
165 // ACCESSORS
166
167 /// Call the wrapped `functor` with the specified `arg` and return the result.
168 ///
169 /// \note Note that `ARG_TYPE` will typically be deduced as a `const`
170 /// type.
171 template <class ARG_TYPE>
172 std::size_t operator()(ARG_TYPE& arg) const;
173
174 /// Return a reference providing non-modifiable access to the hash
175 /// functor wrapped by this object.
176 const FUNCTOR& functor() const;
177};
178
179/// This partial specialization handles `const` qualified functors, that may
180/// not be stored as a `mutable` member in the primary template. The need
181/// to wrap such functors diminishes greatly, as there is no need to play
182/// mutable tricks to invoke the function call operator. An alternative to
183/// providing this specialization would be to skip the wrapper entirely if using a `const` qualified functor in a `HashTable`.
184///
185/// \note Note that this type
186/// has a `const` qualified data member, so is neither assignable nor
187/// swappable.
188template <class FUNCTOR>
189class HashTable_HashWrapper<const FUNCTOR> {
190
191 private:
192 const FUNCTOR d_functor;
193
194 public:
195 // CREATORS
196
197 /// Create a `HashTable_HashWrapper` object wrapping a `FUNCTOR` that
198 /// has its default value.
200
201 /// Create a `HashTable_HashWrapper` object wrapping a `FUNCTOR` that is
202 /// a copy of the specified `fn`.
203 explicit HashTable_HashWrapper(const FUNCTOR& fn);
204
205 // ACCESSORS
206
207 /// Call the wrapped `functor` with the specified `arg` and return the result.
208 ///
209 /// \note Note that `ARG_TYPE` will typically be deduced as a `const`
210 /// type.
211 template <class ARG_TYPE>
212 std::size_t operator()(ARG_TYPE& arg) const;
213
214 /// Return a reference providing non-modifiable access to the hash
215 /// functor wrapped by this object.
216 const FUNCTOR& functor() const;
217};
218
219/// This partial specialization handles `const` qualified functors, that may
220/// not be stored as a `mutable` member in the primary template.
221///
222/// \note Note that the `FUNCTOR` type itself may be `const`-qualified, so this one partial
223/// template specialization also handles `const FUNCTOR&` references. In
224/// order to correctly parse with the reference-binding rules, we drop the
225/// `const` in front of many of the references to `FUNCTOR` seen in the primary template definition.
226///
227/// \note Note that this type has a reference data
228/// member, so is not default constructible, assignable or swappable.
229template <class FUNCTOR>
230class HashTable_HashWrapper<FUNCTOR &> {
231
232 private:
233 FUNCTOR& d_functor;
234
235 public:
236 // CREATORS
237
238 /// Create a `HashTable_HashWrapper` object wrapping a `FUNCTOR` that is
239 /// a copy of the specified `fn`.
240 explicit HashTable_HashWrapper(FUNCTOR& fn);
241
242 // ACCESSORS
243
244 /// Call the wrapped `functor` with the specified `arg` and return the result.
245 ///
246 /// \note Note that `ARG_TYPE` will typically be deduced as a `const`
247 /// type.
248 template <class ARG_TYPE>
249 std::size_t operator()(ARG_TYPE& arg) const;
250
251 /// Return a reference providing non-modifiable access to the hash
252 /// functor wrapped by this object.
253 FUNCTOR& functor() const;
254};
255
256/// Swap the functor wrapped by the specified `a` object with the functor
257/// wrapped by the specified `b` object.
258template <class FUNCTOR>
259void swap(HashTable_HashWrapper<FUNCTOR> &a,
260 HashTable_HashWrapper<FUNCTOR> &b);
261
262 // =================================
263 // class HashTable_ComparatorWrapper
264 // =================================
265
266/// This class provides a wrapper around a functor that can compare two
267/// values and return a `bool`, so that the function call operator is always
268/// declared as `const` qualified.
269///
270/// TBD Provide an optimization for the case of an empty base functor, where
271/// we can safely const_cast want calling the base class operator.
272///
273/// See @ref bslstl_hashtable_cpp03
274template <class FUNCTOR>
275class HashTable_ComparatorWrapper {
276
277 private:
278 mutable FUNCTOR d_functor;
279
280 public:
281 // CREATORS
282
283 /// Create a `HashTable_ComparatorWrapper` object wrapping a `FUNCTOR`
284 /// that has its default value.
286
287 /// Create a `HashTable_ComparatorWrapper` object wrapping a `FUNCTOR`
288 /// that is a copy of the specified `fn`.
289 explicit HashTable_ComparatorWrapper(const FUNCTOR& fn);
290
291 // MANIPULATORS
292
293 /// Exchange the value of this object with the specified `other` object.
295
296 // ACCESSORS
297
298 /// Call the wrapped `functor` with the specified `arg1` and `arg2` (in that order) and return the result.
299 ///
300 /// \note Note that `ARGn_TYPE` will
301 /// typically be deduced as a `const` type.
302 template <class ARG1_TYPE, class ARG2_TYPE>
303 bool operator()(ARG1_TYPE& arg1, ARG2_TYPE& arg2) const;
304
305 /// Return a reference providing non-modifiable access to the hash
306 /// functor wrapped by this object.
307 const FUNCTOR& functor() const;
308};
309
310/// This partial specialization handles `const` qualified functors, that may
311/// not be stored as a `mutable` member in the primary template. The need
312/// to wrap such functors diminishes greatly, as there is no need to play
313/// mutable tricks to invoke the function call operator. An alternative to
314/// providing this specialization would be to skip the wrapper entirely if using a `const` qualified functor in a `HashTable`.
315///
316/// \note Note that this type
317/// has a `const` qualified data member, so is neither assignable nor
318/// swappable.
319template <class FUNCTOR>
320class HashTable_ComparatorWrapper<const FUNCTOR> {
321
322 private:
323 const FUNCTOR d_functor;
324
325 public:
326 // CREATORS
327
328 /// Create a `HashTable_ComparatorWrapper` object wrapping a `FUNCTOR`
329 /// that has its default value.
331
332 /// Create a `HashTable_ComparatorWrapper` object wrapping a `FUNCTOR`
333 /// that is a copy of the specified `fn`.
334 explicit HashTable_ComparatorWrapper(const FUNCTOR& fn);
335
336 // ACCESSORS
337
338 /// Call the wrapped `functor` with the specified `arg1` and `arg2` (in that order) and return the result.
339 ///
340 /// \note Note that `ARGn_TYPE` will
341 /// typically be deduced as a `const` type.
342 template <class ARG1_TYPE, class ARG2_TYPE>
343 bool operator()(ARG1_TYPE& arg1, ARG2_TYPE& arg2) const;
344
345 /// Return a reference providing non-modifiable access to the hash
346 /// functor wrapped by this object.
347 const FUNCTOR& functor() const;
348};
349
350/// This partial specialization handles `const` qualified functors, that may
351/// not be stored as a `mutable` member in the primary template.
352///
353/// \note Note that the `FUNCTOR` type itself may be `const`-qualified, so this one partial
354/// template specialization also handles `const FUNCTOR&` references. In
355/// order to correctly parse with the reference-binding rules, we drop the
356/// `const` in front of many of the references to `FUNCTOR` seen in the primary template definition.
357///
358/// \note Note that this type has a reference data
359/// member, so is not default constructible, assignable or swappable.
360template <class FUNCTOR>
361class HashTable_ComparatorWrapper<FUNCTOR &> {
362
363 private:
364 FUNCTOR& d_functor;
365
366 public:
367 // CREATORS
368
369 /// Create a `HashTable_ComparatorWrapper` object wrapping a `FUNCTOR`
370 /// that is a copy of the specified `fn`.
371 explicit HashTable_ComparatorWrapper(FUNCTOR& fn);
372
373 // ACCESSORS
374
375 /// Call the wrapped `functor` with the specified `arg1` and `arg2` (in that order) and return the result.
376 ///
377 /// \note Note that `ARGn_TYPE` will
378 /// typically be deduced as a `const` type.
379 template <class ARG1_TYPE, class ARG2_TYPE>
380 bool operator()(ARG1_TYPE& arg1, ARG2_TYPE& arg2) const;
381
382 /// Return a reference providing non-modifiable access to the hash
383 /// functor wrapped by this object.
384 FUNCTOR& functor() const;
385};
386
387/// Swap the functor wrapped by the specified `lhs` object with the functor
388/// wrapped by the specified `rhs` object.
389template <class FUNCTOR>
390void swap(HashTable_ComparatorWrapper<FUNCTOR> &lhs,
391 HashTable_ComparatorWrapper<FUNCTOR> &rhs);
392
393 // ===============
394 // class HashTable
395 // ===============
396
397template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
398class HashTable_ImplParameters;
399
400/// This class template implements a value-semantic container type holding
401/// an unordered sequence of (possibly duplicate) elements, that can be
402/// rapidly accessed using their key, with the constraint on the container
403/// that elements whose keys compare equal according to the specified
404/// `COMPARATOR` will be stored in a stable, contiguous sequence within the
405/// container. The value type and key type of the elements maintained by a
406/// `HashTable` are determined by aliases provided through the (template
407/// parameter) type `KEY_CONFIG`. Elements in a `HashTable` are stored in
408/// "nodes" that are allocated using an allocator of the specified
409/// `ALLOCATOR` type (rebound to the node type), and elements are
410/// constructed directly in the node using the allocator as described in the
411/// C++11 standard under the allocator-aware container requirements in
412/// ([container.requirements.general], C++11 23.2.1). The (template
413/// parameter) types `HASHER` and `COMPARATOR` shall be `copy-constructible`
414/// function-objects. `HASHER` shall support a function call operator
415/// compatible with the following statements:
416/// @code
417/// HASHER hash;
418/// KEY_CONFIG::KeyType key;
419/// std::size_t result = hash(key);
420/// @endcode
421/// where the definition of the called function meets the requirements of a
422/// hash function, as specified in @ref bslstl_hash . `COMPARATOR` shall
423/// support the a function call operator compatible with the following
424/// statements:
425/// @code
426/// COMPARATOR compare;
427/// KEY_CONFIG::KeyType key1, key2;
428/// bool result = compare(key1, key2);
429/// @endcode
430/// where the definition of the called function defines an equivalence
431/// relationship on keys that is both reflexive and transitive. The
432/// `HASHER` and `COMPARATOR` attributes of this class are further
433/// constrained, such for any two objects whose keys compare equal by the
434/// comparator, shall produce the same value from the hasher.
435///
436/// This class:
437/// * supports a complete set of *value-semantic* operations
438/// - except for `bdex` serialization
439/// * is *exception-neutral* (agnostic except for the `at` method)
440/// * is *alias-safe*
441/// * is `const` *thread-safe*
442/// For terminology see @ref bsldoc_glossary .
443///
444/// See @ref bslstl_hashtable_cpp03
445template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
446class HashTable {
447
448 public:
449 // TYPES
450 typedef ALLOCATOR AllocatorType;
451 typedef ::bsl::allocator_traits<AllocatorType> AllocatorTraits;
452 typedef typename KEY_CONFIG::KeyType KeyType;
453 typedef typename KEY_CONFIG::ValueType ValueType;
455 typedef typename AllocatorTraits::size_type SizeType;
457
458 private:
459 // PRIVATE TYPES
460 typedef
461 HashTable_ImplParameters<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>
462 ImplParameters;
463
464 /// This typedef is a convenient alias for the utility associated with
465 /// movable references.
466 typedef bslmf::MovableRefUtil MoveUtil;
467
468 // CONSISTENCY CHECKS
469
470 // Assert consistency checks against Machiavellian users, specializing an
471 // allocator for a specific type to have different propagation traits to
472 // the primary template.
473
474 typedef typename AllocatorTraits::template rebind_traits<NodeType>
475 ReboundTraits;
476
478 ReboundTraits::propagate_on_container_copy_assignment::value ==
479 AllocatorTraits::propagate_on_container_copy_assignment::value);
480
482 ReboundTraits::propagate_on_container_move_assignment::value ==
483 AllocatorTraits::propagate_on_container_move_assignment::value);
484
485 BSLMF_ASSERT(ReboundTraits::propagate_on_container_swap::value ==
486 AllocatorTraits::propagate_on_container_swap::value);
487
488 private:
489 // DATA
490 ImplParameters d_parameters; // policies governing table behavior
492 d_anchor; // list root and bucket array
493 SizeType d_size; // number of elements in this table
494 SizeType d_capacity; // max number of elements before a
495 // rehash is required (computed from
496 // 'd_maxLoadFactor')
497 float d_maxLoadFactor; // maximum permitted load factor
498
499 private:
500 // PRIVATE MANIPULATORS
501
502 /// Copy the sequence of elements from the list starting at the
503 /// specified `cursor` and having `size` elements. Allocate a bucket
504 /// array sufficiently large to store `size` elements while respecting
505 /// the `maxLoadFactor`, and index the copied list into that new array
506 /// of hash buckets. This hash table then takes ownership of the list and bucket array.
507 ///
508 /// \note Note that this method is intended to be called
509 /// from copy constructors, which will have assigned some initial values
510 /// for the `size` and other attributes that may not be consistent with
511 /// the class invariants until after this method is called.
512 void copyDataStructure(bslalg::BidirectionalLink *cursor);
513
514 /// Recreate the sequence of elements from the list starting at the
515 /// specified `cursor` and having (member) `d_size` elements, ensuring
516 /// that each `ValueType` object in the source list is move-inserted
517 /// into the new sequence. Allocate a bucket array sufficiently large
518 /// to store `d_size` elements, while respecting the `maxLoadFactor`,
519 /// and index the new list into that new array of hash buckets. This
520 /// hash table then takes ownership of the list and bucket array.
521 ///
522 /// \note Note that this method is intended to be called from move constructors
523 /// (where the source and target allocators do not match), which will
524 /// have assigned some initial values for the `size` and other
525 /// attributes that may not be consistent with the class invariants
526 /// until after this method completes. If an exception is thrown during
527 /// this operation, this object is left in a valid but unspecified
528 /// state; it is the caller's responsibility, however, to ensure the
529 /// source hash-table is in a valid state if an exception is thrown
530 void moveDataStructure(bslalg::BidirectionalLink *cursor);
531
532 /// Efficiently exchange the value, functors, and allocator of this
533 /// object with those of the specified `other` object. This method
534 /// provides the no-throw exception-safety guarantee.
535 void quickSwapExchangeAllocators(HashTable *other);
536
537 /// Efficiently exchange the value and functors this object with those
538 /// of the specified `other` object. This method provides the no-throw exception-safety guarantee.
539 ///
540 /// \pre The behavior is undefined unless this
541 /// object was created with the same allocator as `other`.
542 void quickSwapRetainAllocators(HashTable *other);
543
544 /// Re-organize this hash-table to have exactly the specified
545 /// `newNumBuckets`, which will then be able to store the specified
546 /// `capacity` number of elements without exceeding the `maxLoadFactor`.
547 /// This operation provides the strong exception guarantee (see
548 /// @ref bsldoc_glossary ) unless the `hasher` throws, in which case this
549 /// operation provides the basic exception guarantee, leaving the
550 /// hash-table in a valid, but otherwise unspecified (and potentially empty), state.
551 ///
552 /// \pre The behavior is undefined unless `size / newNumBuckets <= maxLoadFactor`.
553 ///
554 /// \note Note that the caller is
555 /// responsible for correctly computing the `capacity` supported by the
556 /// new number of buckets. This allows for a minor optimization where
557 /// the value is computed only once per rehash.
558 void rehashIntoExactlyNumBuckets(SizeType newNumBuckets,
559 SizeType capacity);
560
561 /// Erase all the nodes in this hash-table, and deallocate their memory
562 /// via the supplied node-factory. Destroy the array of buckets owned
563 /// by this hash-table. If `d_anchor.bucketAddress()` is the default
564 /// bucket address (`HashTable_ImpDetails::defaultBucketAddress`), then
565 /// this hash-table does not own its array of buckets, and it will not
566 /// be destroyed.
567 void removeAllAndDeallocate();
568
569 /// Erase all the nodes in this table and deallocate their memory via
570 /// the node factory, without performing the necessary bookkeeping to reflect such change.
571 ///
572 /// \note Note that this (private) method explicitly
573 /// leaves the HashTable in an inconsistent state, and is expected to be
574 /// useful when the anchor of this hash table is about to be overwritten
575 /// with a new value, or when the hash table is going out of scope and
576 /// the extra bookkeeping is not necessary.
577 void removeAllImp();
578
579 // PRIVATE ACCESSORS
580
581 /// Return the address of the first node in this hash table having a key
582 /// that compares equal (according to this hash-table's `comparator`) to the specified `key`.
583 ///
584 /// \pre The behavior is undefined unless the specified
585 /// `hashValue` is the hash code for the `key` according to the `hasher` functor of this hash table.
586 ///
587 /// \note Note that this function's
588 /// implementation relies on the supplied `hashValue` rather than
589 /// recomputing it, eliminating some redundant computation for the
590 /// public methods.
591 template <class DEDUCED_KEY>
592 bslalg::BidirectionalLink *find(DEDUCED_KEY& key,
593 std::size_t hashValue) const;
594
595 /// Return the address of the bucket at the specified `bucketIndex` in bucket array of this hash table.
596 ///
597 /// \pre The behavior is undefined unless
598 /// `bucketIndex < this->numBuckets()`.
599 bslalg::HashTableBucket *getBucketAddress(SizeType bucketIndex) const;
600
601 /// Return the hash code for the element stored in the specified `node`
602 /// using a copy of the hash functor supplied at construction.
603 ///
604 /// \pre The behavior is undefined unless `node` points to a list-node of type
605 /// `bslalg::BidirectionalNode<KEY_CONFIG::ValueType>`.
606 std::size_t hashCodeForNode(bslalg::BidirectionalLink *node) const;
607
608 public:
609 // CREATORS
610
611 /// Create an empty hash-table. Optionally specify a `basicAllocator`
612 /// used to supply memory. If `basicAllocator` is not supplied, a
613 /// default-constructed object of the (template parameter) type
614 /// `ALLOCATOR` is used. If the type `ALLOCATOR` is `bsl::allocator`
615 /// and `basicAllocator` is not supplied, the currently installed
616 /// default allocator is used to supply memory. Use 1.0 for the
617 /// `maxLoadFactor`. Use a default constructed object of the (template
618 /// parameter) type `HASHER` and a default constructed object of the
619 /// (template parameter) type `COMPARATOR` to organize elements in the
620 /// table. No memory is allocated unless the `HASHER` or `COMPARATOR` types allocate memory in their default constructor.
621 ///
622 /// \note Note that a
623 /// `bslma::Allocator *` can be supplied for `basicAllocator` if the
624 /// type `ALLOCATOR` is `bsl::allocator` (the default).
625 explicit HashTable(const ALLOCATOR& basicAllocator = ALLOCATOR());
626
627 /// Create an empty hash-table using the specified `hash` and `compare`
628 /// functors to organize elements in the table, which will initially
629 /// have at least the specified `initialNumBuckets` and a
630 /// `maxLoadFactor` of the specified `initialMaxLoadFactor`. Optionally
631 /// specify a `basicAllocator` used to supply memory. If
632 /// `basicAllocator` is not supplied, a default-constructed object of
633 /// the (template parameter) type `ALLOCATOR` is used. If the type
634 /// `ALLOCATOR` is `bsl::allocator` and `basicAllocator` is not
635 /// supplied, the currently installed default allocator is used to
636 /// supply memory. If this constructor tries to allocate a number of
637 /// buckets larger than can be represented by this hash-table's
638 /// `SizeType`, a `std::length_error` exception is thrown.
639 ///
640 /// \pre The behavior is undefined unless `0 < initialMaxLoadFactor`.
641 /// \note Note that more than
642 /// `initialNumBuckets` buckets may be created in order to preserve the
643 /// bucket allocation strategy of the hash-table (but never fewer).
644 /// Also note that a `bslma::Allocator *` can be supplied for
645 /// `basicAllocator` if the type `ALLOCATOR` is `bsl::allocator` (the
646 /// default).
647 HashTable(const HASHER& hash,
648 const COMPARATOR& compare,
649 SizeType initialNumBuckets,
650 float initialMaxLoadFactor,
651 const ALLOCATOR& basicAllocator = ALLOCATOR());
652
653 /// Create a hash-table having the same value (and `maxLoadFactor`) as
654 /// the specified `original` object. Use a copy of `original.hasher()`
655 /// and a copy of `original.comparator()` to organize elements in this
656 /// hash-table. Use the allocator returned by
657 /// 'bsl::allocator_traits<ALLOCATOR>::
658 /// select_on_container_copy_construction(original.allocator())'
659 /// to allocate memory. This method requires that the `ValueType`
660 /// defined by the (template parameter) type `KEY_CONFIG` be
661 /// `copy-insertable` into this hash-table (see '{Requirements on `KEY_CONFIG`}).
662 ///
663 /// \note Note that this hash-table may have fewer buckets
664 /// than `original`, and a correspondingly higher `loadFactor`, so long
665 /// as `maxLoadFactor` is not exceeded. Also note that the created hash
666 /// table may have a different `numBuckets` than `original`, and a
667 /// correspondingly different `loadFactor`, as long as `maxLoadFactor`
668 /// is not exceeded.
669 HashTable(const HashTable& original);
670
671 /// Create a hash-table having the same value (and `maxLoadFactor`) as
672 /// the specified `original` object by moving (in constant time) the
673 /// contents of `original` to the new hash-table. Use a copy of
674 /// `original.hasher()` and a copy of `original.comparator()` to
675 /// organize elements in this hash-table. The allocator associated with
676 /// `original` is propagated for use in the newly created hash-table.
677 /// `original` is left in a valid but unspecified state.
678 HashTable(BloombergLP::bslmf::MovableRef<HashTable> original);
679
680 /// Create a hash-table having the same value (and `maxLoadFactor`) as
681 /// the specified `original` object that uses the specified
682 /// `basicAllocator` to supply memory. Use a copy of
683 /// `original.hasher()` and a copy of `original.comparator()` to
684 /// organize elements in this hash-table. This method requires that the
685 /// `ValueType` defined by the (template parameter) type `KEY_CONFIG` be `move-insertable` into this hash-table.
686 ///
687 /// \note Note that this hash-table
688 /// may have a different `numBuckets` than `original`, and a
689 /// correspondingly different `loadFactor`, as long as `maxLoadFactor`
690 /// is not exceeded.
691 HashTable(const HashTable& original, const ALLOCATOR& basicAllocator);
692
693 /// Create a hash table having the same value (and `maxLoadFactor`) as
694 /// the specified `original` object that uses the specified
695 /// `basicAllocator` to supply memory. The contents of `original` are
696 /// moved (in constant time) to the new hash-table if
697 /// `basicAllocator == original.get_allocator()`, and are move-inserted
698 /// (in linear time) using `basicAllocator` otherwise. `original` is
699 /// left in a valid but unspecified state. Use a copy of
700 /// `original.hasher()` and a copy of `original.comparator()` to
701 /// organize elements in this hash-table. This method requires that the
702 /// `ValueType` defined by the (template parameter) type `KEY_CONFIG` be `move-insertable` into this hash-table.
703 ///
704 /// \note Note that this hash-table
705 /// may have a different `numBuckets` than `original`, and a
706 /// correspondingly different `loadFactor`, as long as `maxLoadFactor`
707 /// is not exceeded. Also note that a `bslma::Allocator *` can be
708 /// supplied for `basicAllocator` if the (template parameter)
709 /// `ALLOCATOR` is `bsl::allocator` (the default).
710 HashTable(BloombergLP::bslmf::MovableRef<HashTable> original,
711 const ALLOCATOR& basicAllocator);
712
713 /// Destroy this object.
714 ~HashTable();
715
716 // MANIPULATORS
717
718 /// Assign to this object the value, hasher, comparator and
719 /// `maxLoadFactor` of the specified `rhs` object, propagate to this
720 /// object the allocator of `rhs` if the `ALLOCATOR` type has trait
721 /// @ref propagate_on_container_copy_assignment , and return a reference
722 /// providing modifiable access to this object. This method requires
723 /// that the `ValueType` defined by the (template parameter) type
724 /// `KEY_CONFIG` be `copy-assignable` and `copy-insertable` into this
725 /// hash-table (see {Requirements on `KEY_CONFIG`}). This method
726 /// requires that the (template parameter) types `HASHER` and
727 /// `COMPARATOR` be `copy-constructible` and `copy-assignable`.
728 ///
729 /// \note Note that these requirements are modeled after the unordered container
730 /// requirements table in the C++11 standard, which is imprecise on this
731 /// operation; these requirements might simplify in the future, if the
732 /// standard is updated.
733 HashTable& operator=(const HashTable& rhs);
734
735 /// Assign to this object the value, hasher, comparator, and
736 /// `maxLoadFactor` of the specified `rhs` object, propagate to this
737 /// object the allocator of `rhs` if the `ALLOCATOR` type has trait
738 /// @ref propagate_on_container_move_assignment , and return a reference
739 /// providing modifiable access to this object. If this hash-table and
740 /// `rhs` use the same allocator (after considering the aforementioned
741 /// trait), all of the contents of `rhs` are moved to this hash-table in
742 /// constant time; otherwise, all elements in this hash table are either
743 /// destroyed or move-assigned to and each additional element in `rhs`
744 /// is move-inserted into this hash-table. `rhs` is left in a valid but
745 /// unspecified state. This method requires that the `ValueType`
746 /// defined by the (template parameter) type `KEY_CONFIG` be both
747 /// `move-assignable` and `move-insertable` into this hash-table (see
748 /// {Requirements on `KEY_CONFIG`}).
749 HashTable& operator=(BloombergLP::bslmf::MovableRef<HashTable> rhs);
750
751#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
752// {{{ BEGIN GENERATED CODE
753// Command line: sim_cpp11_features.pl bslstl_hashtable.h
754#ifndef BSLSTL_HASHTABLE_VARIADIC_LIMIT
755#define BSLSTL_HASHTABLE_VARIADIC_LIMIT 10
756#endif
757#ifndef BSLSTL_HASHTABLE_VARIADIC_LIMIT_A
758#define BSLSTL_HASHTABLE_VARIADIC_LIMIT_A BSLSTL_HASHTABLE_VARIADIC_LIMIT
759#endif
760#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 0
762 );
763#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 0
764
765#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 1
766 template <class Args_01>
768 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01);
769#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 1
770
771#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 2
772 template <class Args_01,
773 class Args_02>
775 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
776 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02);
777#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 2
778
779#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 3
780 template <class Args_01,
781 class Args_02,
782 class Args_03>
784 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
785 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
786 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03);
787#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 3
788
789#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 4
790 template <class Args_01,
791 class Args_02,
792 class Args_03,
793 class Args_04>
795 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
796 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
797 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
798 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04);
799#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 4
800
801#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 5
802 template <class Args_01,
803 class Args_02,
804 class Args_03,
805 class Args_04,
806 class Args_05>
808 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
809 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
810 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
811 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
812 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05);
813#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 5
814
815#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 6
816 template <class Args_01,
817 class Args_02,
818 class Args_03,
819 class Args_04,
820 class Args_05,
821 class Args_06>
823 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
824 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
825 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
826 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
827 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
828 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06);
829#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 6
830
831#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 7
832 template <class Args_01,
833 class Args_02,
834 class Args_03,
835 class Args_04,
836 class Args_05,
837 class Args_06,
838 class Args_07>
840 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
841 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
842 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
843 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
844 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
845 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
846 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07);
847#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 7
848
849#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 8
850 template <class Args_01,
851 class Args_02,
852 class Args_03,
853 class Args_04,
854 class Args_05,
855 class Args_06,
856 class Args_07,
857 class Args_08>
859 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
860 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
861 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
862 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
863 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
864 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
865 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
866 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08);
867#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 8
868
869#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 9
870 template <class Args_01,
871 class Args_02,
872 class Args_03,
873 class Args_04,
874 class Args_05,
875 class Args_06,
876 class Args_07,
877 class Args_08,
878 class Args_09>
880 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
881 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
882 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
883 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
884 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
885 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
886 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
887 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08,
888 BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) arguments_09);
889#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 9
890
891#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 10
892 template <class Args_01,
893 class Args_02,
894 class Args_03,
895 class Args_04,
896 class Args_05,
897 class Args_06,
898 class Args_07,
899 class Args_08,
900 class Args_09,
901 class Args_10>
903 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
904 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
905 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
906 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
907 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
908 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
909 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
910 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08,
911 BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) arguments_09,
912 BSLS_COMPILERFEATURES_FORWARD_REF(Args_10) arguments_10);
913#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 10
914
915
916#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 0
919#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 0
920
921#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 1
922 template <class Args_01>
925 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01);
926#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 1
927
928#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 2
929 template <class Args_01,
930 class Args_02>
933 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
934 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02);
935#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 2
936
937#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 3
938 template <class Args_01,
939 class Args_02,
940 class Args_03>
943 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
944 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
945 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03);
946#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 3
947
948#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 4
949 template <class Args_01,
950 class Args_02,
951 class Args_03,
952 class Args_04>
955 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
956 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
957 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
958 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04);
959#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 4
960
961#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 5
962 template <class Args_01,
963 class Args_02,
964 class Args_03,
965 class Args_04,
966 class Args_05>
969 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
970 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
971 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
972 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
973 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05);
974#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 5
975
976#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 6
977 template <class Args_01,
978 class Args_02,
979 class Args_03,
980 class Args_04,
981 class Args_05,
982 class Args_06>
985 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
986 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
987 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
988 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
989 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
990 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06);
991#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 6
992
993#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 7
994 template <class Args_01,
995 class Args_02,
996 class Args_03,
997 class Args_04,
998 class Args_05,
999 class Args_06,
1000 class Args_07>
1003 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
1004 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
1005 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
1006 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
1007 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
1008 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
1009 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07);
1010#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 7
1011
1012#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 8
1013 template <class Args_01,
1014 class Args_02,
1015 class Args_03,
1016 class Args_04,
1017 class Args_05,
1018 class Args_06,
1019 class Args_07,
1020 class Args_08>
1023 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
1024 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
1025 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
1026 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
1027 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
1028 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
1029 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
1030 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08);
1031#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 8
1032
1033#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 9
1034 template <class Args_01,
1035 class Args_02,
1036 class Args_03,
1037 class Args_04,
1038 class Args_05,
1039 class Args_06,
1040 class Args_07,
1041 class Args_08,
1042 class Args_09>
1045 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
1046 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
1047 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
1048 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
1049 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
1050 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
1051 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
1052 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08,
1053 BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) arguments_09);
1054#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 9
1055
1056#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 10
1057 template <class Args_01,
1058 class Args_02,
1059 class Args_03,
1060 class Args_04,
1061 class Args_05,
1062 class Args_06,
1063 class Args_07,
1064 class Args_08,
1065 class Args_09,
1066 class Args_10>
1069 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
1070 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
1071 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
1072 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
1073 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
1074 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
1075 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
1076 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08,
1077 BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) arguments_09,
1078 BSLS_COMPILERFEATURES_FORWARD_REF(Args_10) arguments_10);
1079#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 10
1080
1081
1082#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 0
1083 bslalg::BidirectionalLink *emplaceIfMissing(bool *isInsertedFlag);
1084#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 0
1085
1086#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 1
1087 template <class Args_01>
1088 bslalg::BidirectionalLink *emplaceIfMissing(bool *isInsertedFlag,
1089 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01);
1090#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 1
1091
1092#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 2
1093 template <class Args_01,
1094 class Args_02>
1095 bslalg::BidirectionalLink *emplaceIfMissing(bool *isInsertedFlag,
1096 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
1097 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02);
1098#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 2
1099
1100#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 3
1101 template <class Args_01,
1102 class Args_02,
1103 class Args_03>
1104 bslalg::BidirectionalLink *emplaceIfMissing(bool *isInsertedFlag,
1105 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
1106 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
1107 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03);
1108#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 3
1109
1110#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 4
1111 template <class Args_01,
1112 class Args_02,
1113 class Args_03,
1114 class Args_04>
1115 bslalg::BidirectionalLink *emplaceIfMissing(bool *isInsertedFlag,
1116 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
1117 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
1118 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
1119 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04);
1120#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 4
1121
1122#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 5
1123 template <class Args_01,
1124 class Args_02,
1125 class Args_03,
1126 class Args_04,
1127 class Args_05>
1128 bslalg::BidirectionalLink *emplaceIfMissing(bool *isInsertedFlag,
1129 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
1130 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
1131 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
1132 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
1133 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05);
1134#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 5
1135
1136#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 6
1137 template <class Args_01,
1138 class Args_02,
1139 class Args_03,
1140 class Args_04,
1141 class Args_05,
1142 class Args_06>
1143 bslalg::BidirectionalLink *emplaceIfMissing(bool *isInsertedFlag,
1144 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
1145 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
1146 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
1147 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
1148 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
1149 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06);
1150#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 6
1151
1152#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 7
1153 template <class Args_01,
1154 class Args_02,
1155 class Args_03,
1156 class Args_04,
1157 class Args_05,
1158 class Args_06,
1159 class Args_07>
1160 bslalg::BidirectionalLink *emplaceIfMissing(bool *isInsertedFlag,
1161 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
1162 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
1163 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
1164 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
1165 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
1166 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
1167 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07);
1168#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 7
1169
1170#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 8
1171 template <class Args_01,
1172 class Args_02,
1173 class Args_03,
1174 class Args_04,
1175 class Args_05,
1176 class Args_06,
1177 class Args_07,
1178 class Args_08>
1179 bslalg::BidirectionalLink *emplaceIfMissing(bool *isInsertedFlag,
1180 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
1181 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
1182 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
1183 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
1184 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
1185 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
1186 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
1187 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08);
1188#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 8
1189
1190#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 9
1191 template <class Args_01,
1192 class Args_02,
1193 class Args_03,
1194 class Args_04,
1195 class Args_05,
1196 class Args_06,
1197 class Args_07,
1198 class Args_08,
1199 class Args_09>
1200 bslalg::BidirectionalLink *emplaceIfMissing(bool *isInsertedFlag,
1201 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
1202 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
1203 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
1204 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
1205 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
1206 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
1207 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
1208 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08,
1209 BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) arguments_09);
1210#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 9
1211
1212#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 10
1213 template <class Args_01,
1214 class Args_02,
1215 class Args_03,
1216 class Args_04,
1217 class Args_05,
1218 class Args_06,
1219 class Args_07,
1220 class Args_08,
1221 class Args_09,
1222 class Args_10>
1223 bslalg::BidirectionalLink *emplaceIfMissing(bool *isInsertedFlag,
1224 BSLS_COMPILERFEATURES_FORWARD_REF(Args_01) arguments_01,
1225 BSLS_COMPILERFEATURES_FORWARD_REF(Args_02) arguments_02,
1226 BSLS_COMPILERFEATURES_FORWARD_REF(Args_03) arguments_03,
1227 BSLS_COMPILERFEATURES_FORWARD_REF(Args_04) arguments_04,
1228 BSLS_COMPILERFEATURES_FORWARD_REF(Args_05) arguments_05,
1229 BSLS_COMPILERFEATURES_FORWARD_REF(Args_06) arguments_06,
1230 BSLS_COMPILERFEATURES_FORWARD_REF(Args_07) arguments_07,
1231 BSLS_COMPILERFEATURES_FORWARD_REF(Args_08) arguments_08,
1232 BSLS_COMPILERFEATURES_FORWARD_REF(Args_09) arguments_09,
1233 BSLS_COMPILERFEATURES_FORWARD_REF(Args_10) arguments_10);
1234#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_A >= 10
1235
1236#else
1237// The generated code below is a workaround for the absence of perfect
1238// forwarding in some compilers.
1239 template <class... Args>
1241 BSLS_COMPILERFEATURES_FORWARD_REF(Args)... arguments);
1242
1243 template <class... Args>
1246 BSLS_COMPILERFEATURES_FORWARD_REF(Args)... arguments);
1247
1248 template <class... Args>
1249 bslalg::BidirectionalLink *emplaceIfMissing(bool *isInsertedFlag,
1250 BSLS_COMPILERFEATURES_FORWARD_REF(Args)... arguments);
1251// }}} END GENERATED CODE
1252#endif
1253
1254 /// Insert into this hash-table a newly-created `ValueType` object,
1255 /// constructed by forwarding the specified `key` and a
1256 /// default-constructed object of the type `ValueType::second_type`, to
1257 /// the corresponding constructor of `ValueType`, if `key` does not
1258 /// already exist in this hash-table. Return the address of the
1259 /// (possibly newly created and inserted) element in this hash-table
1260 /// whose key is equivalent to `key`. If this hash-table contains more
1261 /// than one element with the supplied `key`, return the first such
1262 /// element (from the contiguous sequence of elements having a matching
1263 /// key). Additional buckets are allocated, as needed, to preserve the
1264 /// invariant `loadFactor <= maxLoadFactor`. If this function tries to
1265 /// allocate a number of buckets larger than can be represented by this
1266 /// hash table's `SizeType`, a `std::length_error` exception is thrown.
1267 /// This method requires that the `ValueType` defined in the (template
1268 /// parameter) type `KEY_CONFIG` be `emplace-constructible` into this
1269 /// hash-table from a `pair` of arguments representing the key and
1270 /// value, respectively (see {Requirements on `KEY_CONFIG`});
1274
1275 /// Insert the specified `value` into this hash-table if a key
1276 /// equivalent to that of `value` does not already exist in this
1277 /// hash-table. Return the address of the (possibly newly inserted)
1278 /// element in this hash-table whose key is equivalent to that of
1279 /// `value`. If this hash-table contains more than one element with a
1280 /// matching key, return the first such element (from the contiguous
1281 /// sequence of elements having a matching key). Additional buckets are
1282 /// allocated, as needed, to preserve the invariant
1283 /// `loadFactor <= maxLoadFactor`. If this function tries to allocate a
1284 /// number of buckets larger than can be represented by this
1285 /// hash-table's `SizeType`, a `std::length_error` exception is thrown.
1286 /// This method requires that the `ValueType` defined in the (template
1287 /// parameter) type `KEY_CONFIG` be `copy-insertable` into this
1288 /// hash-table (see {Requirements on `KEY_CONFIG`});
1290 bool *isInsertedFlag,
1291 const ValueType& value);
1292
1293 /// Insert the specified `value` into this hash-table if a key
1294 /// equivalent to that of `value` does not already exist in this
1295 /// hash-table. Return the address of the (possibly newly inserted)
1296 /// element in this hash-table whose key is equivalent to that of
1297 /// `value`. `value` is left in a valid but unspecified state. If this
1298 /// hash-table contains more than one element with a matching key,
1299 /// return the first such element (from the contiguous sequence of
1300 /// elements having a matching key). Additional buckets are allocated,
1301 /// as needed, to preserve the invariant `loadFactor <= maxLoadFactor`.
1302 /// If this function tries to allocate a number of buckets larger than
1303 /// can be represented by this hash-table's `SizeType`, a
1304 /// `std::length_error` exception is thrown. This method requires that
1305 /// the `ValueType` defined in the (template parameter) type
1306 /// `KEY_CONFIG` be `move-insertable` into this hash-table (see
1307 /// {Requirements on `KEY_CONFIG`});
1309 bool *isInsertedFlag,
1311
1312 /// Insert into this hash-table a `ValueType` object created from the
1313 /// specified `value` if a key equivalent to that of such an object does
1314 /// not already exist in this hash-table. Return the address of the
1315 /// (possibly newly inserted) element in this hash-table whose key is
1316 /// equivalent to that of the object created from `value`. Load `true`
1317 /// into the specified `isInsertedFlag` if a new value was inserted, and
1318 /// `false` if an equivalent key was already present. If this
1319 /// hash-table contains more than one element with an equivalent key,
1320 /// return the first such element (from the contiguous sequence of
1321 /// elements having a matching key). Additional buckets are allocated,
1322 /// as needed, to preserve the invariant `loadFactor <= maxLoadFactor`.
1323 /// If this function tries to allocate a number of buckets larger than
1324 /// can be represented by this hash-table's `SizeType`, a
1325 /// `std::length_error` exception is thrown. This method requires that
1326 /// the `ValueType` defined in the (template parameter) type
1327 /// `KEY_CONFIG` be `move-insertable` into this hash-table (see
1328 /// {Requirements on `KEY_CONFIG`}) and the (template parameter) type
1329 /// `SOURCE_TYPE` be implicitly convertible to `ValueType`.
1330 template <class SOURCE_TYPE>
1333 bool *isInsertedFlag,
1334 BSLS_COMPILERFEATURES_FORWARD_REF(SOURCE_TYPE) value);
1335
1336// {{{ BEGIN GENERATED CODE
1337// The generated code below is a workaround for the absence of perfect
1338// forwarding in some compilers.
1339 template <class LOOKUP_KEY>
1340 typename bsl::enable_if<
1341 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
1342 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value
1343 , bslalg::BidirectionalLink *>::type
1345 bool *isInsertedFlag,
1346 BSLS_COMPILERFEATURES_FORWARD_REF(LOOKUP_KEY) value)
1347 {
1348
1349 BSLS_ASSERT(isInsertedFlag);
1350
1351 const LOOKUP_KEY& lvalue = value;
1352
1353 size_t hashCode = this->d_parameters.hashCodeForTransparentKey(lvalue);
1354
1355 bslalg::BidirectionalLink *position =
1356 bslalg::HashTableImpUtil::findTransparent<KEY_CONFIG>(
1357 d_anchor,
1358 lvalue,
1359 d_parameters.comparator(),
1360 hashCode);
1361
1362 *isInsertedFlag = (!position);
1363
1364 if(!position) {
1365 if (d_size >= d_capacity) {
1366 this->rehashForNumBuckets(numBuckets() * 2);
1367 }
1368
1369 position = d_parameters.nodeFactory().emplaceIntoNewNode(
1370 BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, value));
1372 position,
1373 hashCode);
1374 ++d_size;
1375 }
1376
1377 return position;
1378 }
1379// }}} END GENERATED CODE
1380
1381 /// Insert into this hash-table a `ValueType` object created from the
1382 /// specified `value` and return the address of the newly inserted node.
1383 /// If a key equivalent to that of the newly-created object already
1384 /// exists in this hash-table, then insert the new object immediately
1385 /// before the first such element. Additional buckets are allocated, as
1386 /// needed, to preserve the invariant `loadFactor <= maxLoadFactor`. If
1387 /// this function tries to allocate a number of buckets larger than can
1388 /// be represented by this hash-table's `SizeType`, a
1389 /// `std::length_error` exception is thrown. This method requires that
1390 /// the `ValueType` defined in the (template parameter) type
1391 /// `KEY_CONFIG` be `move-insertable` into this hash-table (see
1392 /// {Requirements on `KEY_CONFIG`}) and the (template parameter) type
1393 /// `SOURCE_TYPE` be implicitly convertible to `ValueType`.
1394 ///
1395 /// \note Note that this method is deprecated is provided only to ensure backward
1396 /// compatibility with existing clients; use the `emplace` method
1397 /// instead.
1398 template <class SOURCE_TYPE>
1400 BSLS_COMPILERFEATURES_FORWARD_REF(SOURCE_TYPE) value);
1401
1402 /// Insert into this hash-table a `ValueType` object created from the
1403 /// specified `value` (immediately preceding the specified `hint` if
1404 /// `hint` is not null and the key of the node pointed to by `hint` is
1405 /// equivalent to that of the newly-created object), and return the
1406 /// address of the newly inserted node. If `hint` is null or the key of
1407 /// the node pointed to by `hint` is not equivalent to that of the newly
1408 /// created object, and a key equivalent to that of the newly-created
1409 /// object already exists in this hash-table, then insert the
1410 /// newly-created object immediately before the first such element.
1411 /// Additional buckets will be allocated, as needed, to preserve the
1412 /// invariant `loadFactor <= maxLoadFactor`. If this function tries to
1413 /// allocate a number of buckets larger than can be represented by this
1414 /// hash-table's `SizeType`, a `std::length_error` exception is thrown.
1415 /// This method requires that `ValueType` defined in the (template
1416 /// parameter) type `KEY_CONFIG` be `move-insertable` into this
1417 /// hash-table (see {Requirements on `KEY_CONFIG`}) and the (template
1418 /// parameter) type `SOURCE_TYPE` be implicitly convertible to `ValueType`.
1419 ///
1420 /// \note Note that this method is deprecated and is provided
1421 /// only to ensure backward compatibility with existing clients; use the
1422 /// `emplaceWithHint` method instead.
1423 template <class SOURCE_TYPE>
1425 BSLS_COMPILERFEATURES_FORWARD_REF(SOURCE_TYPE) value,
1427
1428// {{{ BEGIN GENERATED CODE
1429// The generated code below is a workaround for the absence of perfect
1430// forwarding in some compilers.
1431 template <class KEY_ARG, class BDE_OTHER_TYPE>
1433 bool *isInsertedFlag,
1436 BSLS_COMPILERFEATURES_FORWARD_REF(BDE_OTHER_TYPE) obj);
1437
1438 template <class LOOKUP_KEY, class BDE_OTHER_TYPE>
1439 typename bsl::enable_if<
1440 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
1441 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value
1442 , bslalg::BidirectionalLink *>::type
1443 insertOrAssignTransparent(bool *isInsertedFlag,
1445 BSLS_COMPILERFEATURES_FORWARD_REF(LOOKUP_KEY) key,
1446 BSLS_COMPILERFEATURES_FORWARD_REF(BDE_OTHER_TYPE) obj)
1447 {
1448
1449 typedef bslalg::HashTableImpUtil ImpUtil;
1450
1451 size_t hashCode = this->d_parameters.hashCodeForTransparentKey(key);
1452 if (!hint
1453 || !d_parameters.comparator()(key,
1454 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
1455 hint = bslalg::HashTableImpUtil::findTransparent<KEY_CONFIG>(
1456 d_anchor,
1457 key,
1458 d_parameters.comparator(),
1459 hashCode);
1460 }
1461
1462 if (hint) {
1463 static_cast<NodeType *>(hint)->value().second =
1464 BSLS_COMPILERFEATURES_FORWARD(BDE_OTHER_TYPE, obj);
1465 *isInsertedFlag = false;
1466 return hint;
1467 }
1468
1469 if (d_size >= d_capacity) {
1470 this->rehashForNumBuckets(numBuckets() * 2);
1471 }
1472
1473 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
1474 BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key),
1475 BSLS_COMPILERFEATURES_FORWARD(BDE_OTHER_TYPE, obj));
1476
1477 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
1478 nodeProctor(&d_parameters.nodeFactory(), hint);
1479 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
1480 nodeProctor.release();
1481 ++d_size;
1482
1483 *isInsertedFlag = true;
1484 return hint;
1485 }
1486// }}} END GENERATED CODE
1487
1488 /// Re-organize this hash-table to have at least the specified
1489 /// `newNumBuckets`, preserving the invariant
1490 /// `loadFactor <= maxLoadFactor`. If this function tries to allocate a
1491 /// number of buckets larger than can be represented by this hash
1492 /// table's `SizeType`, a `std::length_error` exception is thrown. This
1493 /// operation provides the strong exception guarantee (see
1494 /// @ref bsldoc_glossary ) unless the `hasher` throws, in which case this
1495 /// operation provides the basic exception guarantee, leaving the
1496 /// hash-table in a valid, but otherwise unspecified (and potentially empty), state.
1497 ///
1498 /// \note Note that more buckets than requested may be
1499 /// allocated in order to preserve the bucket allocation strategy of the
1500 /// hash table (but never fewer).
1501 void rehashForNumBuckets(SizeType newNumBuckets);
1502
1503 /// Remove the specified `node` from this hash-table, and return the
1504 /// address of the node immediately after `node` in this hash-table
1505 /// (prior to its removal), or a null pointer value if `node` is the
1506 /// last node in the table. This method invalidates only iterators and
1507 /// references to the removed node and previously saved values of the
1508 /// `end()` iterator, and preserves the relative order of the nodes not removed.
1509 ///
1510 /// \pre The behavior is undefined unless `node` refers to a node
1511 /// in this hash-table.
1513
1514 /// Remove all the elements from this hash-table.
1515 /// \note Note that this
1516 /// hash-table is empty after this call, but allocated memory may be
1517 /// retained for future use. The destructor of each (non-trivial)
1518 /// element that is remove shall be run.
1519 void removeAll();
1520
1521 /// Re-organize this hash-table to have a sufficient number of buckets
1522 /// to accommodate at least the specified `numElements` without
1523 /// exceeding the `maxLoadFactor`, and ensure that there are sufficient
1524 /// nodes pre-allocated in this object's node pool. If this function
1525 /// tries to allocate a number of buckets larger than can be represented
1526 /// by this hash table's `SizeType`, a `std::length_error` exception is
1527 /// thrown. This operation provides the strong exception guarantee (see
1528 /// @ref bsldoc_glossary ) unless the `hasher` throws, in which case this
1529 /// operation provides the basic exception guarantee, leaving the
1530 /// hash-table in a valid, but otherwise unspecified (and potentially
1531 /// empty), state.
1532 void reserveForNumElements(SizeType numElements);
1533
1534 /// Set the maximum load factor permitted by this hash table to the
1535 /// specified `newMaxLoadFactor`, where load factor is the statistical
1536 /// mean number of elements per bucket. If 'newMaxLoadFactor <
1537 /// loadFactor', allocate at least enough buckets to re-establish the
1538 /// invariant `loadFactor <= maxLoadFactor`. If this function tries to
1539 /// allocate a number of buckets larger than can be represented by this
1540 /// hash table's `SizeType`, a `std::length_error` exception is thrown.
1541 ///
1542 /// \pre The behavior is undefined unless `0 < maxLoadFactor`.
1543 void setMaxLoadFactor(float newMaxLoadFactor);
1544
1545 /// Exchange the value of this object, its `comparator` functor, its
1546 /// `hasher` functor, and its `maxLoadFactor` with those of the
1547 /// specified `other` object. Additionally, if
1548 /// `bslstl::AllocatorTraits<ALLOCATOR>::propagate_on_container_swap` is
1549 /// `true`, then exchange the allocator of this object with that of the
1550 /// `other` object, and do not modify either allocator otherwise. This
1551 /// method provides the no-throw exception-safety guarantee unless any
1552 /// of the `comparator` or `hasher` functors throw when swapped, leaving
1553 /// both objects in a safely destructible, but otherwise unusable,
1554 /// state. The operation guarantees `O[1]` complexity.
1555 ///
1556 /// \pre The behavior is undefined unless either this object has an allocator that compares
1557 /// equal to the allocator of `other`, or the trait
1558 /// `bslstl::AllocatorTraits<ALLOCATOR>::propagate_on_container_swap` is
1559 /// `true`.
1560 void swap(HashTable& other);
1561
1562#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
1563// {{{ BEGIN GENERATED CODE
1564// Command line: sim_cpp11_features.pl bslstl_hashtable.h
1565#ifndef BSLSTL_HASHTABLE_VARIADIC_LIMIT
1566#define BSLSTL_HASHTABLE_VARIADIC_LIMIT 10
1567#endif
1568#ifndef BSLSTL_HASHTABLE_VARIADIC_LIMIT_D
1569#define BSLSTL_HASHTABLE_VARIADIC_LIMIT_D BSLSTL_HASHTABLE_VARIADIC_LIMIT
1570#endif
1571#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 0
1573 bool *isInsertedFlag,
1575 const KeyType& key);
1576#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 0
1577
1578#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 1
1579 template <class ARGS_01>
1581 bool *isInsertedFlag,
1583 const KeyType& key,
1584 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01);
1585#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 1
1586
1587#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 2
1588 template <class ARGS_01,
1589 class ARGS_02>
1591 bool *isInsertedFlag,
1593 const KeyType& key,
1594 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1595 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02);
1596#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 2
1597
1598#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 3
1599 template <class ARGS_01,
1600 class ARGS_02,
1601 class ARGS_03>
1603 bool *isInsertedFlag,
1605 const KeyType& key,
1606 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1607 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1608 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03);
1609#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 3
1610
1611#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 4
1612 template <class ARGS_01,
1613 class ARGS_02,
1614 class ARGS_03,
1615 class ARGS_04>
1617 bool *isInsertedFlag,
1619 const KeyType& key,
1620 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1621 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1622 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
1623 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04);
1624#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 4
1625
1626#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 5
1627 template <class ARGS_01,
1628 class ARGS_02,
1629 class ARGS_03,
1630 class ARGS_04,
1631 class ARGS_05>
1633 bool *isInsertedFlag,
1635 const KeyType& key,
1636 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1637 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1638 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
1639 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
1640 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05);
1641#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 5
1642
1643#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 6
1644 template <class ARGS_01,
1645 class ARGS_02,
1646 class ARGS_03,
1647 class ARGS_04,
1648 class ARGS_05,
1649 class ARGS_06>
1651 bool *isInsertedFlag,
1653 const KeyType& key,
1654 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1655 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1656 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
1657 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
1658 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
1659 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06);
1660#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 6
1661
1662#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 7
1663 template <class ARGS_01,
1664 class ARGS_02,
1665 class ARGS_03,
1666 class ARGS_04,
1667 class ARGS_05,
1668 class ARGS_06,
1669 class ARGS_07>
1671 bool *isInsertedFlag,
1673 const KeyType& key,
1674 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1675 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1676 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
1677 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
1678 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
1679 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
1680 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07);
1681#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 7
1682
1683#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 8
1684 template <class ARGS_01,
1685 class ARGS_02,
1686 class ARGS_03,
1687 class ARGS_04,
1688 class ARGS_05,
1689 class ARGS_06,
1690 class ARGS_07,
1691 class ARGS_08>
1693 bool *isInsertedFlag,
1695 const KeyType& key,
1696 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1697 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1698 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
1699 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
1700 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
1701 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
1702 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
1703 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08);
1704#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 8
1705
1706#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 9
1707 template <class ARGS_01,
1708 class ARGS_02,
1709 class ARGS_03,
1710 class ARGS_04,
1711 class ARGS_05,
1712 class ARGS_06,
1713 class ARGS_07,
1714 class ARGS_08,
1715 class ARGS_09>
1717 bool *isInsertedFlag,
1719 const KeyType& key,
1720 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1721 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1722 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
1723 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
1724 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
1725 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
1726 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
1727 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
1728 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09);
1729#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 9
1730
1731#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 10
1732 template <class ARGS_01,
1733 class ARGS_02,
1734 class ARGS_03,
1735 class ARGS_04,
1736 class ARGS_05,
1737 class ARGS_06,
1738 class ARGS_07,
1739 class ARGS_08,
1740 class ARGS_09,
1741 class ARGS_10>
1743 bool *isInsertedFlag,
1745 const KeyType& key,
1746 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1747 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1748 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
1749 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
1750 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
1751 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
1752 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
1753 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
1754 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
1755 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10);
1756#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 10
1757
1758
1759#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 0
1761 bool *isInsertedFlag,
1764#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 0
1765
1766#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 1
1767 template <class ARGS_01>
1769 bool *isInsertedFlag,
1772 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01);
1773#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 1
1774
1775#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 2
1776 template <class ARGS_01,
1777 class ARGS_02>
1779 bool *isInsertedFlag,
1782 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1783 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02);
1784#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 2
1785
1786#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 3
1787 template <class ARGS_01,
1788 class ARGS_02,
1789 class ARGS_03>
1791 bool *isInsertedFlag,
1794 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1795 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1796 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03);
1797#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 3
1798
1799#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 4
1800 template <class ARGS_01,
1801 class ARGS_02,
1802 class ARGS_03,
1803 class ARGS_04>
1805 bool *isInsertedFlag,
1808 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1809 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1810 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
1811 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04);
1812#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 4
1813
1814#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 5
1815 template <class ARGS_01,
1816 class ARGS_02,
1817 class ARGS_03,
1818 class ARGS_04,
1819 class ARGS_05>
1821 bool *isInsertedFlag,
1824 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1825 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1826 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
1827 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
1828 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05);
1829#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 5
1830
1831#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 6
1832 template <class ARGS_01,
1833 class ARGS_02,
1834 class ARGS_03,
1835 class ARGS_04,
1836 class ARGS_05,
1837 class ARGS_06>
1839 bool *isInsertedFlag,
1842 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1843 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1844 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
1845 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
1846 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
1847 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06);
1848#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 6
1849
1850#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 7
1851 template <class ARGS_01,
1852 class ARGS_02,
1853 class ARGS_03,
1854 class ARGS_04,
1855 class ARGS_05,
1856 class ARGS_06,
1857 class ARGS_07>
1859 bool *isInsertedFlag,
1862 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1863 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1864 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
1865 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
1866 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
1867 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
1868 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07);
1869#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 7
1870
1871#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 8
1872 template <class ARGS_01,
1873 class ARGS_02,
1874 class ARGS_03,
1875 class ARGS_04,
1876 class ARGS_05,
1877 class ARGS_06,
1878 class ARGS_07,
1879 class ARGS_08>
1881 bool *isInsertedFlag,
1884 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1885 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1886 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
1887 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
1888 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
1889 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
1890 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
1891 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08);
1892#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 8
1893
1894#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 9
1895 template <class ARGS_01,
1896 class ARGS_02,
1897 class ARGS_03,
1898 class ARGS_04,
1899 class ARGS_05,
1900 class ARGS_06,
1901 class ARGS_07,
1902 class ARGS_08,
1903 class ARGS_09>
1905 bool *isInsertedFlag,
1908 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1909 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1910 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
1911 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
1912 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
1913 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
1914 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
1915 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
1916 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09);
1917#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 9
1918
1919#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 10
1920 template <class ARGS_01,
1921 class ARGS_02,
1922 class ARGS_03,
1923 class ARGS_04,
1924 class ARGS_05,
1925 class ARGS_06,
1926 class ARGS_07,
1927 class ARGS_08,
1928 class ARGS_09,
1929 class ARGS_10>
1931 bool *isInsertedFlag,
1934 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
1935 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
1936 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
1937 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
1938 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
1939 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
1940 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
1941 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
1942 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
1943 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10);
1944#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 10
1945
1946
1947
1948#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 0
1949 template <class LOOKUP_KEY>
1950 typename bsl::enable_if<
1951 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
1952 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
1954 bool *isInsertedFlag,
1956 BSLS_COMPILERFEATURES_FORWARD_REF(LOOKUP_KEY) key)
1957 {
1958
1959 typedef bslalg::HashTableImpUtil ImpUtil;
1960
1961 const std::size_t hashCode =
1962 this->d_parameters.hashCodeForTransparentKey(key);
1963
1964 if (!hint
1965 || !d_parameters.comparator()(
1966 key,
1967 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
1968
1969 hint = bslalg::HashTableImpUtil::findTransparent<KEY_CONFIG>(
1970 d_anchor,
1971 key,
1972 d_parameters.comparator(),
1973 hashCode);
1974 }
1975
1976 if (hint) {
1977 *isInsertedFlag = false;
1978 return hint;
1979 }
1980
1981 if (d_size >= d_capacity) {
1982 this->rehashForNumBuckets(numBuckets() * 2);
1983 }
1984
1985 #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
1986 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
1987 std::piecewise_construct,
1988 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key)),
1989 std::forward_as_tuple());
1990 #else
1991 typedef typename ValueType::second_type MappedType;
1992
1993
1994 AllocatorType alloc = this->allocator();
1995
1996 bsls::ObjectBuffer<MappedType> defaultMapped;
1997 AllocatorTraits::construct(alloc, defaultMapped.address());
1998 bslma::DestructorGuard<MappedType> mGuard(defaultMapped.address());
1999
2000 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2001 BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key),
2002 defaultMapped.object());
2003 #endif
2004
2005 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
2006 nodeProctor(&d_parameters.nodeFactory(), hint);
2007 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
2008 nodeProctor.release();
2009 ++d_size;
2010
2011 *isInsertedFlag = true;
2012 return hint;
2013 }
2014#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 0
2015
2016#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 1
2017 template <class LOOKUP_KEY, class ARGS_01>
2018 typename bsl::enable_if<
2019 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
2020 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
2022 bool *isInsertedFlag,
2024 BSLS_COMPILERFEATURES_FORWARD_REF(LOOKUP_KEY) key,
2025 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01)
2026 {
2027
2028 typedef bslalg::HashTableImpUtil ImpUtil;
2029
2030 const std::size_t hashCode =
2031 this->d_parameters.hashCodeForTransparentKey(key);
2032
2033 if (!hint
2034 || !d_parameters.comparator()(
2035 key,
2036 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
2037
2038 hint = bslalg::HashTableImpUtil::findTransparent<KEY_CONFIG>(
2039 d_anchor,
2040 key,
2041 d_parameters.comparator(),
2042 hashCode);
2043 }
2044
2045 if (hint) {
2046 *isInsertedFlag = false;
2047 return hint;
2048 }
2049
2050 if (d_size >= d_capacity) {
2051 this->rehashForNumBuckets(numBuckets() * 2);
2052 }
2053
2054 #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
2055 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2056 std::piecewise_construct,
2057 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key)),
2058 std::forward_as_tuple(
2059 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01)));
2060 #else
2061 typedef typename ValueType::second_type MappedType;
2062
2063
2064 AllocatorType alloc = this->allocator();
2065
2066 bsls::ObjectBuffer<MappedType> defaultMapped;
2067 AllocatorTraits::construct(alloc, defaultMapped.address(),
2068 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01));
2069 bslma::DestructorGuard<MappedType> mGuard(defaultMapped.address());
2070
2071 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2072 BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key),
2073 defaultMapped.object());
2074 #endif
2075
2076 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
2077 nodeProctor(&d_parameters.nodeFactory(), hint);
2078 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
2079 nodeProctor.release();
2080 ++d_size;
2081
2082 *isInsertedFlag = true;
2083 return hint;
2084 }
2085#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 1
2086
2087#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 2
2088 template <class LOOKUP_KEY, class ARGS_01,
2089 class ARGS_02>
2090 typename bsl::enable_if<
2091 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
2092 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
2094 bool *isInsertedFlag,
2096 BSLS_COMPILERFEATURES_FORWARD_REF(LOOKUP_KEY) key,
2097 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
2098 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02)
2099 {
2100
2101 typedef bslalg::HashTableImpUtil ImpUtil;
2102
2103 const std::size_t hashCode =
2104 this->d_parameters.hashCodeForTransparentKey(key);
2105
2106 if (!hint
2107 || !d_parameters.comparator()(
2108 key,
2109 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
2110
2111 hint = bslalg::HashTableImpUtil::findTransparent<KEY_CONFIG>(
2112 d_anchor,
2113 key,
2114 d_parameters.comparator(),
2115 hashCode);
2116 }
2117
2118 if (hint) {
2119 *isInsertedFlag = false;
2120 return hint;
2121 }
2122
2123 if (d_size >= d_capacity) {
2124 this->rehashForNumBuckets(numBuckets() * 2);
2125 }
2126
2127 #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
2128 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2129 std::piecewise_construct,
2130 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key)),
2131 std::forward_as_tuple(
2132 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2133 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02)));
2134 #else
2135 typedef typename ValueType::second_type MappedType;
2136
2137
2138 AllocatorType alloc = this->allocator();
2139
2140 bsls::ObjectBuffer<MappedType> defaultMapped;
2141 AllocatorTraits::construct(alloc, defaultMapped.address(),
2142 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2143 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02));
2144 bslma::DestructorGuard<MappedType> mGuard(defaultMapped.address());
2145
2146 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2147 BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key),
2148 defaultMapped.object());
2149 #endif
2150
2151 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
2152 nodeProctor(&d_parameters.nodeFactory(), hint);
2153 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
2154 nodeProctor.release();
2155 ++d_size;
2156
2157 *isInsertedFlag = true;
2158 return hint;
2159 }
2160#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 2
2161
2162#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 3
2163 template <class LOOKUP_KEY, class ARGS_01,
2164 class ARGS_02,
2165 class ARGS_03>
2166 typename bsl::enable_if<
2167 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
2168 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
2170 bool *isInsertedFlag,
2172 BSLS_COMPILERFEATURES_FORWARD_REF(LOOKUP_KEY) key,
2173 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
2174 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
2175 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03)
2176 {
2177
2178 typedef bslalg::HashTableImpUtil ImpUtil;
2179
2180 const std::size_t hashCode =
2181 this->d_parameters.hashCodeForTransparentKey(key);
2182
2183 if (!hint
2184 || !d_parameters.comparator()(
2185 key,
2186 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
2187
2188 hint = bslalg::HashTableImpUtil::findTransparent<KEY_CONFIG>(
2189 d_anchor,
2190 key,
2191 d_parameters.comparator(),
2192 hashCode);
2193 }
2194
2195 if (hint) {
2196 *isInsertedFlag = false;
2197 return hint;
2198 }
2199
2200 if (d_size >= d_capacity) {
2201 this->rehashForNumBuckets(numBuckets() * 2);
2202 }
2203
2204 #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
2205 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2206 std::piecewise_construct,
2207 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key)),
2208 std::forward_as_tuple(
2209 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2210 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2211 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03)));
2212 #else
2213 typedef typename ValueType::second_type MappedType;
2214
2215
2216 AllocatorType alloc = this->allocator();
2217
2218 bsls::ObjectBuffer<MappedType> defaultMapped;
2219 AllocatorTraits::construct(alloc, defaultMapped.address(),
2220 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2221 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2222 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03));
2223 bslma::DestructorGuard<MappedType> mGuard(defaultMapped.address());
2224
2225 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2226 BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key),
2227 defaultMapped.object());
2228 #endif
2229
2230 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
2231 nodeProctor(&d_parameters.nodeFactory(), hint);
2232 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
2233 nodeProctor.release();
2234 ++d_size;
2235
2236 *isInsertedFlag = true;
2237 return hint;
2238 }
2239#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 3
2240
2241#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 4
2242 template <class LOOKUP_KEY, class ARGS_01,
2243 class ARGS_02,
2244 class ARGS_03,
2245 class ARGS_04>
2246 typename bsl::enable_if<
2247 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
2248 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
2250 bool *isInsertedFlag,
2252 BSLS_COMPILERFEATURES_FORWARD_REF(LOOKUP_KEY) key,
2253 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
2254 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
2255 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
2256 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04)
2257 {
2258
2259 typedef bslalg::HashTableImpUtil ImpUtil;
2260
2261 const std::size_t hashCode =
2262 this->d_parameters.hashCodeForTransparentKey(key);
2263
2264 if (!hint
2265 || !d_parameters.comparator()(
2266 key,
2267 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
2268
2269 hint = bslalg::HashTableImpUtil::findTransparent<KEY_CONFIG>(
2270 d_anchor,
2271 key,
2272 d_parameters.comparator(),
2273 hashCode);
2274 }
2275
2276 if (hint) {
2277 *isInsertedFlag = false;
2278 return hint;
2279 }
2280
2281 if (d_size >= d_capacity) {
2282 this->rehashForNumBuckets(numBuckets() * 2);
2283 }
2284
2285 #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
2286 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2287 std::piecewise_construct,
2288 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key)),
2289 std::forward_as_tuple(
2290 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2291 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2292 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
2293 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04)));
2294 #else
2295 typedef typename ValueType::second_type MappedType;
2296
2297
2298 AllocatorType alloc = this->allocator();
2299
2300 bsls::ObjectBuffer<MappedType> defaultMapped;
2301 AllocatorTraits::construct(alloc, defaultMapped.address(),
2302 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2303 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2304 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
2305 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04));
2306 bslma::DestructorGuard<MappedType> mGuard(defaultMapped.address());
2307
2308 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2309 BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key),
2310 defaultMapped.object());
2311 #endif
2312
2313 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
2314 nodeProctor(&d_parameters.nodeFactory(), hint);
2315 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
2316 nodeProctor.release();
2317 ++d_size;
2318
2319 *isInsertedFlag = true;
2320 return hint;
2321 }
2322#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 4
2323
2324#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 5
2325 template <class LOOKUP_KEY, class ARGS_01,
2326 class ARGS_02,
2327 class ARGS_03,
2328 class ARGS_04,
2329 class ARGS_05>
2330 typename bsl::enable_if<
2331 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
2332 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
2334 bool *isInsertedFlag,
2336 BSLS_COMPILERFEATURES_FORWARD_REF(LOOKUP_KEY) key,
2337 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
2338 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
2339 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
2340 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
2341 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05)
2342 {
2343
2344 typedef bslalg::HashTableImpUtil ImpUtil;
2345
2346 const std::size_t hashCode =
2347 this->d_parameters.hashCodeForTransparentKey(key);
2348
2349 if (!hint
2350 || !d_parameters.comparator()(
2351 key,
2352 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
2353
2354 hint = bslalg::HashTableImpUtil::findTransparent<KEY_CONFIG>(
2355 d_anchor,
2356 key,
2357 d_parameters.comparator(),
2358 hashCode);
2359 }
2360
2361 if (hint) {
2362 *isInsertedFlag = false;
2363 return hint;
2364 }
2365
2366 if (d_size >= d_capacity) {
2367 this->rehashForNumBuckets(numBuckets() * 2);
2368 }
2369
2370 #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
2371 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2372 std::piecewise_construct,
2373 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key)),
2374 std::forward_as_tuple(
2375 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2376 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2377 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
2378 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
2379 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05)));
2380 #else
2381 typedef typename ValueType::second_type MappedType;
2382
2383
2384 AllocatorType alloc = this->allocator();
2385
2386 bsls::ObjectBuffer<MappedType> defaultMapped;
2387 AllocatorTraits::construct(alloc, defaultMapped.address(),
2388 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2389 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2390 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
2391 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
2392 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05));
2393 bslma::DestructorGuard<MappedType> mGuard(defaultMapped.address());
2394
2395 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2396 BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key),
2397 defaultMapped.object());
2398 #endif
2399
2400 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
2401 nodeProctor(&d_parameters.nodeFactory(), hint);
2402 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
2403 nodeProctor.release();
2404 ++d_size;
2405
2406 *isInsertedFlag = true;
2407 return hint;
2408 }
2409#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 5
2410
2411#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 6
2412 template <class LOOKUP_KEY, class ARGS_01,
2413 class ARGS_02,
2414 class ARGS_03,
2415 class ARGS_04,
2416 class ARGS_05,
2417 class ARGS_06>
2418 typename bsl::enable_if<
2419 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
2420 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
2422 bool *isInsertedFlag,
2424 BSLS_COMPILERFEATURES_FORWARD_REF(LOOKUP_KEY) key,
2425 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
2426 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
2427 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
2428 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
2429 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
2430 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06)
2431 {
2432
2433 typedef bslalg::HashTableImpUtil ImpUtil;
2434
2435 const std::size_t hashCode =
2436 this->d_parameters.hashCodeForTransparentKey(key);
2437
2438 if (!hint
2439 || !d_parameters.comparator()(
2440 key,
2441 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
2442
2443 hint = bslalg::HashTableImpUtil::findTransparent<KEY_CONFIG>(
2444 d_anchor,
2445 key,
2446 d_parameters.comparator(),
2447 hashCode);
2448 }
2449
2450 if (hint) {
2451 *isInsertedFlag = false;
2452 return hint;
2453 }
2454
2455 if (d_size >= d_capacity) {
2456 this->rehashForNumBuckets(numBuckets() * 2);
2457 }
2458
2459 #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
2460 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2461 std::piecewise_construct,
2462 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key)),
2463 std::forward_as_tuple(
2464 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2465 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2466 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
2467 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
2468 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
2469 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06)));
2470 #else
2471 typedef typename ValueType::second_type MappedType;
2472
2473
2474 AllocatorType alloc = this->allocator();
2475
2476 bsls::ObjectBuffer<MappedType> defaultMapped;
2477 AllocatorTraits::construct(alloc, defaultMapped.address(),
2478 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2479 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2480 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
2481 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
2482 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
2483 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06));
2484 bslma::DestructorGuard<MappedType> mGuard(defaultMapped.address());
2485
2486 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2487 BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key),
2488 defaultMapped.object());
2489 #endif
2490
2491 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
2492 nodeProctor(&d_parameters.nodeFactory(), hint);
2493 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
2494 nodeProctor.release();
2495 ++d_size;
2496
2497 *isInsertedFlag = true;
2498 return hint;
2499 }
2500#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 6
2501
2502#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 7
2503 template <class LOOKUP_KEY, class ARGS_01,
2504 class ARGS_02,
2505 class ARGS_03,
2506 class ARGS_04,
2507 class ARGS_05,
2508 class ARGS_06,
2509 class ARGS_07>
2510 typename bsl::enable_if<
2511 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
2512 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
2514 bool *isInsertedFlag,
2516 BSLS_COMPILERFEATURES_FORWARD_REF(LOOKUP_KEY) key,
2517 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
2518 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
2519 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
2520 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
2521 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
2522 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
2523 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07)
2524 {
2525
2526 typedef bslalg::HashTableImpUtil ImpUtil;
2527
2528 const std::size_t hashCode =
2529 this->d_parameters.hashCodeForTransparentKey(key);
2530
2531 if (!hint
2532 || !d_parameters.comparator()(
2533 key,
2534 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
2535
2536 hint = bslalg::HashTableImpUtil::findTransparent<KEY_CONFIG>(
2537 d_anchor,
2538 key,
2539 d_parameters.comparator(),
2540 hashCode);
2541 }
2542
2543 if (hint) {
2544 *isInsertedFlag = false;
2545 return hint;
2546 }
2547
2548 if (d_size >= d_capacity) {
2549 this->rehashForNumBuckets(numBuckets() * 2);
2550 }
2551
2552 #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
2553 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2554 std::piecewise_construct,
2555 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key)),
2556 std::forward_as_tuple(
2557 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2558 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2559 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
2560 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
2561 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
2562 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
2563 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07)));
2564 #else
2565 typedef typename ValueType::second_type MappedType;
2566
2567
2568 AllocatorType alloc = this->allocator();
2569
2570 bsls::ObjectBuffer<MappedType> defaultMapped;
2571 AllocatorTraits::construct(alloc, defaultMapped.address(),
2572 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2573 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2574 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
2575 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
2576 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
2577 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
2578 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07));
2579 bslma::DestructorGuard<MappedType> mGuard(defaultMapped.address());
2580
2581 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2582 BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key),
2583 defaultMapped.object());
2584 #endif
2585
2586 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
2587 nodeProctor(&d_parameters.nodeFactory(), hint);
2588 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
2589 nodeProctor.release();
2590 ++d_size;
2591
2592 *isInsertedFlag = true;
2593 return hint;
2594 }
2595#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 7
2596
2597#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 8
2598 template <class LOOKUP_KEY, class ARGS_01,
2599 class ARGS_02,
2600 class ARGS_03,
2601 class ARGS_04,
2602 class ARGS_05,
2603 class ARGS_06,
2604 class ARGS_07,
2605 class ARGS_08>
2606 typename bsl::enable_if<
2607 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
2608 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
2610 bool *isInsertedFlag,
2612 BSLS_COMPILERFEATURES_FORWARD_REF(LOOKUP_KEY) key,
2613 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
2614 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
2615 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
2616 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
2617 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
2618 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
2619 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
2620 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08)
2621 {
2622
2623 typedef bslalg::HashTableImpUtil ImpUtil;
2624
2625 const std::size_t hashCode =
2626 this->d_parameters.hashCodeForTransparentKey(key);
2627
2628 if (!hint
2629 || !d_parameters.comparator()(
2630 key,
2631 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
2632
2633 hint = bslalg::HashTableImpUtil::findTransparent<KEY_CONFIG>(
2634 d_anchor,
2635 key,
2636 d_parameters.comparator(),
2637 hashCode);
2638 }
2639
2640 if (hint) {
2641 *isInsertedFlag = false;
2642 return hint;
2643 }
2644
2645 if (d_size >= d_capacity) {
2646 this->rehashForNumBuckets(numBuckets() * 2);
2647 }
2648
2649 #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
2650 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2651 std::piecewise_construct,
2652 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key)),
2653 std::forward_as_tuple(
2654 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2655 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2656 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
2657 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
2658 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
2659 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
2660 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
2661 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08)));
2662 #else
2663 typedef typename ValueType::second_type MappedType;
2664
2665
2666 AllocatorType alloc = this->allocator();
2667
2668 bsls::ObjectBuffer<MappedType> defaultMapped;
2669 AllocatorTraits::construct(alloc, defaultMapped.address(),
2670 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2671 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2672 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
2673 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
2674 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
2675 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
2676 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
2677 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08));
2678 bslma::DestructorGuard<MappedType> mGuard(defaultMapped.address());
2679
2680 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2681 BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key),
2682 defaultMapped.object());
2683 #endif
2684
2685 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
2686 nodeProctor(&d_parameters.nodeFactory(), hint);
2687 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
2688 nodeProctor.release();
2689 ++d_size;
2690
2691 *isInsertedFlag = true;
2692 return hint;
2693 }
2694#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 8
2695
2696#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 9
2697 template <class LOOKUP_KEY, class ARGS_01,
2698 class ARGS_02,
2699 class ARGS_03,
2700 class ARGS_04,
2701 class ARGS_05,
2702 class ARGS_06,
2703 class ARGS_07,
2704 class ARGS_08,
2705 class ARGS_09>
2706 typename bsl::enable_if<
2707 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
2708 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
2710 bool *isInsertedFlag,
2712 BSLS_COMPILERFEATURES_FORWARD_REF(LOOKUP_KEY) key,
2713 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
2714 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
2715 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
2716 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
2717 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
2718 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
2719 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
2720 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
2721 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09)
2722 {
2723
2724 typedef bslalg::HashTableImpUtil ImpUtil;
2725
2726 const std::size_t hashCode =
2727 this->d_parameters.hashCodeForTransparentKey(key);
2728
2729 if (!hint
2730 || !d_parameters.comparator()(
2731 key,
2732 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
2733
2734 hint = bslalg::HashTableImpUtil::findTransparent<KEY_CONFIG>(
2735 d_anchor,
2736 key,
2737 d_parameters.comparator(),
2738 hashCode);
2739 }
2740
2741 if (hint) {
2742 *isInsertedFlag = false;
2743 return hint;
2744 }
2745
2746 if (d_size >= d_capacity) {
2747 this->rehashForNumBuckets(numBuckets() * 2);
2748 }
2749
2750 #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
2751 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2752 std::piecewise_construct,
2753 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key)),
2754 std::forward_as_tuple(
2755 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2756 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2757 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
2758 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
2759 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
2760 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
2761 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
2762 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08),
2763 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09)));
2764 #else
2765 typedef typename ValueType::second_type MappedType;
2766
2767
2768 AllocatorType alloc = this->allocator();
2769
2770 bsls::ObjectBuffer<MappedType> defaultMapped;
2771 AllocatorTraits::construct(alloc, defaultMapped.address(),
2772 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2773 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2774 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
2775 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
2776 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
2777 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
2778 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
2779 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08),
2780 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09));
2781 bslma::DestructorGuard<MappedType> mGuard(defaultMapped.address());
2782
2783 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2784 BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key),
2785 defaultMapped.object());
2786 #endif
2787
2788 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
2789 nodeProctor(&d_parameters.nodeFactory(), hint);
2790 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
2791 nodeProctor.release();
2792 ++d_size;
2793
2794 *isInsertedFlag = true;
2795 return hint;
2796 }
2797#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 9
2798
2799#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 10
2800 template <class LOOKUP_KEY, class ARGS_01,
2801 class ARGS_02,
2802 class ARGS_03,
2803 class ARGS_04,
2804 class ARGS_05,
2805 class ARGS_06,
2806 class ARGS_07,
2807 class ARGS_08,
2808 class ARGS_09,
2809 class ARGS_10>
2810 typename bsl::enable_if<
2811 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
2812 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
2814 bool *isInsertedFlag,
2816 BSLS_COMPILERFEATURES_FORWARD_REF(LOOKUP_KEY) key,
2817 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
2818 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
2819 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
2820 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
2821 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
2822 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
2823 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
2824 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
2825 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
2826 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10)
2827 {
2828
2829 typedef bslalg::HashTableImpUtil ImpUtil;
2830
2831 const std::size_t hashCode =
2832 this->d_parameters.hashCodeForTransparentKey(key);
2833
2834 if (!hint
2835 || !d_parameters.comparator()(
2836 key,
2837 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
2838
2839 hint = bslalg::HashTableImpUtil::findTransparent<KEY_CONFIG>(
2840 d_anchor,
2841 key,
2842 d_parameters.comparator(),
2843 hashCode);
2844 }
2845
2846 if (hint) {
2847 *isInsertedFlag = false;
2848 return hint;
2849 }
2850
2851 if (d_size >= d_capacity) {
2852 this->rehashForNumBuckets(numBuckets() * 2);
2853 }
2854
2855 #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
2856 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2857 std::piecewise_construct,
2858 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key)),
2859 std::forward_as_tuple(
2860 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2861 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2862 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
2863 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
2864 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
2865 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
2866 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
2867 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08),
2868 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09),
2869 BSLS_COMPILERFEATURES_FORWARD(ARGS_10, args_10)));
2870 #else
2871 typedef typename ValueType::second_type MappedType;
2872
2873
2874 AllocatorType alloc = this->allocator();
2875
2876 bsls::ObjectBuffer<MappedType> defaultMapped;
2877 AllocatorTraits::construct(alloc, defaultMapped.address(),
2878 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
2879 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
2880 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
2881 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
2882 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
2883 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
2884 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
2885 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08),
2886 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09),
2887 BSLS_COMPILERFEATURES_FORWARD(ARGS_10, args_10));
2888 bslma::DestructorGuard<MappedType> mGuard(defaultMapped.address());
2889
2890 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2891 BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key),
2892 defaultMapped.object());
2893 #endif
2894
2895 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
2896 nodeProctor(&d_parameters.nodeFactory(), hint);
2897 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
2898 nodeProctor.release();
2899 ++d_size;
2900
2901 *isInsertedFlag = true;
2902 return hint;
2903 }
2904#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_D >= 10
2905
2906#else
2907// The generated code below is a workaround for the absence of perfect
2908// forwarding in some compilers.
2909 template <class... ARGS>
2911 bool *isInsertedFlag,
2913 const KeyType& key,
2914 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args);
2915
2916 template <class... ARGS>
2918 bool *isInsertedFlag,
2921 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args);
2922
2923
2924 template <class LOOKUP_KEY, class... ARGS>
2925 typename bsl::enable_if<
2926 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
2927 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
2929 bool *isInsertedFlag,
2931 BSLS_COMPILERFEATURES_FORWARD_REF(LOOKUP_KEY) key,
2933 {
2934
2935 typedef bslalg::HashTableImpUtil ImpUtil;
2936
2937 const std::size_t hashCode =
2938 this->d_parameters.hashCodeForTransparentKey(key);
2939
2940 if (!hint
2941 || !d_parameters.comparator()(
2942 key,
2943 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
2944
2945 hint = bslalg::HashTableImpUtil::findTransparent<KEY_CONFIG>(
2946 d_anchor,
2947 key,
2948 d_parameters.comparator(),
2949 hashCode);
2950 }
2951
2952 if (hint) {
2953 *isInsertedFlag = false;
2954 return hint;
2955 }
2956
2957 if (d_size >= d_capacity) {
2958 this->rehashForNumBuckets(numBuckets() * 2);
2959 }
2960
2961 #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
2962 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2963 std::piecewise_construct,
2964 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key)),
2965 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...));
2966 #else
2967 typedef typename ValueType::second_type MappedType;
2968
2969
2970 AllocatorType alloc = this->allocator();
2971
2972 bsls::ObjectBuffer<MappedType> defaultMapped;
2973 AllocatorTraits::construct(alloc, defaultMapped.address(),
2974 BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...);
2975 bslma::DestructorGuard<MappedType> mGuard(defaultMapped.address());
2976
2977 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
2978 BSLS_COMPILERFEATURES_FORWARD(LOOKUP_KEY, key),
2979 defaultMapped.object());
2980 #endif
2981
2982 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
2983 nodeProctor(&d_parameters.nodeFactory(), hint);
2984 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
2985 nodeProctor.release();
2986 ++d_size;
2987
2988 *isInsertedFlag = true;
2989 return hint;
2990 }
2991// }}} END GENERATED CODE
2992#endif
2993
2994 // ACCESSORS
2995
2996 /// Return a copy of the allocator used to construct this hash table.
2997 ///
2998 /// \note Note that this is not the allocator used to allocate elements for
2999 /// this hash table, which is instead a copy of that allocator rebound
3000 /// to allocate the nodes used by the internal data structure of this
3001 /// hash table.
3002 ALLOCATOR allocator() const;
3003
3004 /// Return a reference offering non-modifiable access to the
3005 /// `HashTableBucket` at the specified `index` position in the array of buckets of this table.
3006 ///
3007 /// \pre The behavior is undefined unless 'index <
3008 /// numBuckets()'.
3010
3011 /// Return the index of the bucket that would contain all the elements
3012 /// having the specified `key`.
3013 SizeType bucketIndexForKey(const KeyType& key) const;
3014
3015 /// Return the index of the bucket that would contain all the elements
3016 /// equivalent to the specified `key`.
3017 template <class LOOKUP_KEY>
3018 typename bsl::enable_if<
3019 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
3020 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
3021 SizeType>::type
3022 bucketIndexForKey(const LOOKUP_KEY& key) const
3023 {
3024 // Note: implemented inline due to Sun CC compilation error.
3025
3026 typedef typename
3028 SizeType;
3029
3030 // The following cast will not discard any useful bits, unless
3031 // 'SizeType' is larger than 'size_t', as the bucket computation takes
3032 // a mod on the supplied number of buckets. We use the following
3033 // 'BSLMF_ASSERT' to assert that assumption at compile time.
3034
3035 BSLMF_ASSERT(sizeof(SizeType) <= sizeof(size_t));
3036
3037 size_t hashCode = this->d_parameters.hashCodeForKey(key);
3038 return static_cast<SizeType>(
3040 hashCode,
3041 d_anchor.bucketArraySize()));
3042 }
3043
3044 /// Return a reference providing non-modifiable access to the
3045 /// key-equality comparison functor used by this hash table.
3046 const COMPARATOR& comparator() const;
3047
3048 /// Return the number elements contained in the bucket at the specified `index`.
3049 ///
3050 /// \note Note that this operation has linear run-time complexity
3051 /// with respect to the number of elements in the indexed bucket.
3053
3054 /// Return the address of the first element in this hash table, or a
3055 /// null pointer value if this hash table is empty.
3057
3058 /// Return the address of a link whose key is equivalent to the
3059 /// specified `key` (according to this hash-table's `comparator`), and a
3060 /// null pointer value if no such link exists. If this hash-table
3061 /// contains more than one element having the supplied `key`, return the
3062 /// first such element (from the contiguous sequence of elements having the same key).
3063 ///
3064 /// \pre The behavior is undefined unless `key` is equivalent
3065 /// to the elements of at most one equivalent-key group.
3066 template <class LOOKUP_KEY>
3067 typename bsl::enable_if<
3068 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
3069 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
3071 find(const LOOKUP_KEY& key) const
3072 {
3073 // Note: implemented inline due to Sun CC compilation error.
3074
3075 return bslalg::HashTableImpUtil::findTransparent<KEY_CONFIG>(
3076 d_anchor,
3077 key,
3078 d_parameters.comparator(),
3079 d_parameters.hashCodeForKey(key));
3080 }
3081
3082 /// Return the address of a link whose key has the same value as the
3083 /// specified `key` (according to this hash-table's `comparator`), and a
3084 /// null pointer value if no such link exists. If this hash-table
3085 /// contains more than one element having the supplied `key`, return the
3086 /// first such element (from the contiguous sequence of elements having
3087 /// the same key).
3088 bslalg::BidirectionalLink *find(const KeyType& key) const;
3089
3090 /// Return the address of the first node after any nodes holding a value
3091 /// having the same key as the specified `first` node (according to this
3092 /// hash-table's `comparator`), and a null pointer value if all nodes
3093 /// following `first` hold values with the same key as `first`.
3094 ///
3095 /// \pre The behavior is undefined unless `first` is a link in this hash-table.
3096 ///
3097 /// \note Note that this hash-table ensures all elements having the same key
3098 /// form a contiguous sequence.
3100 bslalg::BidirectionalLink *first) const;
3101
3102 /// Load into the specified `first` and `last` pointers the respective
3103 /// addresses of the first and last link (in the list of elements owned
3104 /// by this hash table) where the contained elements have a key that is
3105 /// equivalent to the specified `key` using the `comparator` of this
3106 /// hash-table, and null pointer values if there are no elements matching `key`.
3107 ///
3108 /// \pre The behavior is undefined unless `key` is
3109 /// equivalent to the elements of at most one equivalent-key group.
3110 ///
3111 /// \note Note that the output values will form a closed range, where both
3112 /// `first` and `last` point to links satisfying the predicate (rather
3113 /// than a semi-open range where `last` would point to the element
3114 /// following the range). Also note that this hash-table ensures all
3115 /// elements having the same key form a contiguous sequence.
3116 template <class LOOKUP_KEY>
3117 typename bsl::enable_if<
3118 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value
3119 && BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,LOOKUP_KEY>::value,
3120 void>::type
3123 const LOOKUP_KEY& key) const
3124 {
3125 // Note: implemented inline due to Sun CC compilation error.
3126
3127 BSLS_ASSERT_SAFE(first);
3128 BSLS_ASSERT_SAFE(last);
3129
3130 *first = this->find(key);
3131 *last = *first ? this->findEndOfRange(*first) : 0;
3132 }
3133
3134 /// Load into the specified `first` and `last` pointers the respective
3135 /// addresses of the first and last link (in the list of elements owned
3136 /// by this hash table) where the contained elements have a key that
3137 /// compares equal to the specified `key` using the `comparator` of this
3138 /// hash-table, and null pointer values if there are no elements matching `key`.
3139 ///
3140 /// \note Note that the output values will form a closed
3141 /// range, where both `first` and `last` point to links satisfying the
3142 /// predicate (rather than a semi-open range where `last` would point to
3143 /// the element following the range). Also note that this hash-table
3144 /// ensures all elements having the same key form a contiguous sequence.
3147 const KeyType& key) const;
3148
3149 /// Return `true` if the specified `other` has the same value as this
3150 /// object, and `false` otherwise. Two `HashTable` objects have the
3151 /// same value if they have the same number of elements, and for every
3152 /// subset of elements in this object having keys that compare equal
3153 /// (according to that hash table's `comparator`), a corresponding
3154 /// subset of elements exists in the `other` object, having the same
3155 /// number of elements, where, for some permutation of the subset in
3156 /// this object, every element in that subset compares equal (using
3157 /// `operator==`) to the corresponding element in the `other` subset.
3158 ///
3159 /// \pre The behavior is undefined unless both the `hasher` and `comparator`
3160 /// of this object and the `other` return the same value for every valid input.
3161 ///
3162 /// \note Note that this method requires that the `ValueType` of the
3163 /// parameterized `KEY_CONFIG` be "equality-comparable" (see
3164 /// {Requirements on `KEY_CONFIG`}).
3165 bool hasSameValue(const HashTable& other) const;
3166
3167 /// Return a reference providing non-modifiable access to the hash
3168 /// functor used by this hash-table.
3169 const HASHER& hasher() const;
3170
3171 /// Return the current load factor for this table. The load factor is
3172 /// the statistical mean number of elements per bucket.
3173 float loadFactor() const;
3174
3175 /// Return the maximum load factor permitted by this hash table object,
3176 /// where the load factor is the statistical mean number of elements per bucket.
3177 ///
3178 /// \note Note that this hash table will enforce the maximum load
3179 /// factor by rehashing into a larger array of buckets on any any
3180 /// insertion operation where a successful insertion would exceed the
3181 /// maximum load factor. The maximum load factor may actually be less
3182 /// than the current load factor if the maximum load factor has been
3183 /// reset, but no insert operations have yet occurred.
3184 float maxLoadFactor() const;
3185
3186 /// Return a theoretical upper bound on the largest number of buckets that this hash-table could possibly have.
3187 ///
3188 /// \note Note that there is no
3189 /// guarantee that the hash-table can successfully maintain that number
3190 /// of buckets, or even close to that number of buckets without running
3191 /// out of resources.
3192 SizeType maxNumBuckets() const;
3193
3194 /// Return a theoretical upper bound on the largest number of elements that this hash-table could possibly hold.
3195 ///
3196 /// \note Note that there is no
3197 /// guarantee that the hash-table can successfully grow to the returned
3198 /// size, or even close to that size without running out of resources.
3199 SizeType maxSize() const;
3200
3201 /// Return the number of buckets contained in this hash table.
3202 SizeType numBuckets() const;
3203
3204 /// Return the number of elements this hash table can hold without
3205 /// requiring a rehash operation in order to respect the
3206 /// `maxLoadFactor`.
3207 SizeType rehashThreshold() const;
3208
3209 /// Return the number of elements in this hash table.
3210 SizeType size() const;
3211};
3212
3213/// Swap both the value, the hasher, the comparator, and the `maxLoadFactor`
3214/// of the specified `x` object with the value, the hasher, the comparator,
3215/// and the `maxLoadFactor` of the specified `y` object. Additionally, if
3216/// `bslstl::AllocatorTraits<ALLOCATOR>::propagate_on_container_swap` is
3217/// `true`, then exchange the allocator of `x` with that of `y`, and do not
3218/// modify either allocator otherwise. This method guarantees `O[1]`
3219/// complexity if `x` and `y` have the same allocator or if the allocators
3220/// propagate on swap, otherwise this operation will typically pay the cost
3221/// of two copy constructors, which may in turn throw. If the allocators
3222/// are the same or propagate, then this method provides the no-throw
3223/// exception-safety guarantee unless the `swap` function of the hasher or
3224/// comparator throw. Otherwise this method offers only the basic exception
3225/// safety guarantee.
3226template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
3227void swap(HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>& x,
3228 HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>& y);
3229
3230/// Return `true` if the specified `lhs` and `rhs` objects have the same
3231/// value, and `false` otherwise. Two `HashTable` objects have the same
3232/// value if they have the same number of elements, and for every subset of
3233/// elements in `lhs` having keys that compare equal (according to that hash
3234/// table's `comparator`), a corresponding subset of elements exists in
3235/// `rhs`, having the same number of elements, where, for some permutation
3236/// of the `lhs` subset, every element in that subset compares equal (using
3237/// `operator==`) to the corresponding element in the `rhs` subset.
3238///
3239/// \pre The behavior is undefined unless both the `hasher` and `comparator` of `lhs` and `rhs` return the same value for every valid input.
3240///
3241/// \note Note that this
3242/// method requires that the `ValueType` of the parameterized `KEY_CONFIG`
3243/// be "equality-comparable" (see {Requirements on `KEY_CONFIG`}).
3244template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
3245bool operator==(
3246 const HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>& lhs,
3247 const HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>& rhs);
3248
3249/// Return `true` if the specified `lhs` and `rhs` objects do not have the
3250/// same value, and `false` otherwise. Two `HashTable` objects do not have
3251/// the same value if they do not have the same number of elements, or if,
3252/// for any key found in `lhs`, the subset of elements having that key
3253/// (according to the hash-table's `comparator`) in `lhs` either (1) does
3254/// not have the same number of elements as the subset of elements having
3255/// that key in `rhs`, or (2) there exists no permutation of the `lhs`
3256/// subset where each element compares equal (using `operator==`) to the
3257/// corresponding element in the `rhs` subset.
3258///
3259/// \pre The behavior is undefined unless both the `hasher` and `comparator` of `lhs` and `rhs` return the same value for every valid input.
3260///
3261/// \note Note that this method requires that
3262/// the `ValueType` of the parameterized `KEY_CONFIG` be
3263/// "equality-comparable" (see {Requirements on `KEY_CONFIG`}).
3264template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
3265bool operator!=(
3266 const HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>& lhs,
3267 const HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>& rhs);
3268
3269 // ============================
3270 // class HashTable_ArrayProctor
3271 // ============================
3272
3273/// This class probably already exists in `bslalg`
3274///
3275/// See @ref bslstl_hashtable_cpp03
3276template <class FACTORY>
3277class HashTable_ArrayProctor {
3278
3279 private:
3280 // DATA
3281 FACTORY *d_factory_p;
3282 bslalg::HashTableAnchor *d_anchor_p;
3283
3284 private:
3285 // NOT IMPLEMENTED
3286 HashTable_ArrayProctor(const HashTable_ArrayProctor&);
3287 HashTable_ArrayProctor& operator=(const HashTable_ArrayProctor&);
3288
3289 public:
3290 // CREATORS
3291
3292 /// Create a `HashTable_ArrayProctor` managing the hash-table data
3293 /// structure owned by the specified `anchor` that was created using the
3294 /// specified `factory`.
3295 HashTable_ArrayProctor(FACTORY *factory,
3296 bslalg::HashTableAnchor *anchor);
3297
3298 /// Destroy the hash-table data structure managed by this proctor and
3299 /// reclaim all of its resources, unless there was a call to `release`
3300 /// this proctor.
3302
3303 // MANIPULATORS
3304
3305 /// Release from management the object currently managed by this
3306 /// proctor. If no object is currently being managed, this method has
3307 /// no effect.
3308 void release();
3309};
3310
3311 // ===========================
3312 // class HashTable_NodeProctor
3313 // ===========================
3314
3315/// This class implements a proctor that, unless its `release` method has
3316/// previously been invoked, automatically deallocates a managed list of
3317/// nodes upon destruction by recursively invoking the `deleteNode` method
3318/// of a supplied factory on each node. The (template parameter) type
3319/// `FACTORY` shall be provide a member function that can be called as if it
3320/// had the following signature:
3321/// @code
3322/// void deleteNode(bslalg::BidirectionalLink *node);
3323/// @endcode
3324///
3325/// See @ref bslstl_hashtable_cpp03
3326template <class FACTORY>
3327class HashTable_NodeProctor {
3328
3329 private:
3330 // DATA
3331 FACTORY *d_factory_p;
3332 bslalg::BidirectionalLink *d_node_p;
3333
3334 private:
3335 // NOT IMPLEMENTED
3336 HashTable_NodeProctor(const HashTable_NodeProctor&);
3337 HashTable_NodeProctor& operator=(const HashTable_NodeProctor&);
3338
3339 public:
3340 // CREATORS
3341
3342 /// Create a new node-proctor that conditionally manages the specified
3343 /// `node` (if non-zero), and that uses the specified `factory` to
3344 /// destroy the node (unless released) upon its destruction.
3345 ///
3346 /// \pre The behavior is undefined unless `node` was created by the `factory`.
3347 HashTable_NodeProctor(FACTORY *factory,
3349
3350 /// Destroy this node proctor, and delete the node that it manages (if
3351 /// any) by invoking the `deleteNode` method of the factory supplied at
3352 /// construction. If no node is currently being managed, this method
3353 /// has no effect.
3355
3356 // MANIPULATORS
3357
3358 /// Release from management the node currently managed by this proctor.
3359 /// If no object is currently being managed, this method has no effect.
3360 void release();
3361};
3362
3363 // ==========================
3364 // class HashTable_ImpDetails
3365 // ==========================
3366
3367/// This utility `struct` provides a namespace for functions that are useful
3368/// when implementing a hash table.
3369///
3370/// See @ref bslstl_hashtable_cpp03
3371struct HashTable_ImpDetails {
3372
3373 // CLASS METHODS
3374
3375 /// Return the address of a statically initialized empty bucket that can
3376 /// be shared as the (un-owned) bucket array by all empty hash tables.
3378
3379 /// Return the suggested number of buckets to index a linked list that
3380 /// can hold as many as the specified `minElements` without exceeding
3381 /// the specified `maxLoadFactor`, and supporting at least the specified
3382 /// number of `requestedBuckets`. Set the specified `*capacity` to the
3383 /// maximum length of linked list that the returned number of buckets
3384 /// could index without exceeding the `maxLoadFactor`.
3385 ///
3386 /// \pre The behavior is undefined unless `0 < maxLoadFactor`, `0 < minElements` and
3387 /// `0 < requestedBuckets`.
3388 static size_t growBucketsForLoadFactor(size_t *capacity,
3389 size_t minElements,
3390 size_t requestedBuckets,
3391 double maxLoadFactor);
3392
3393 /// Return that address of an allocator that can be used to allocate
3394 /// temporary storage, but that is neither the default nor global allocator.
3395 ///
3396 /// \note Note that this function is intended to support detailed
3397 /// checks in `SAFE_2` builds, that may need additional storage for the
3398 /// evaluation of a validity check on a large data structure, but that
3399 /// should not change the expected values computed for regular allocator
3400 /// usage of the component as validated by the test driver.
3402
3403 /// Return the next prime number greater-than or equal to the specified
3404 /// `n` in the increasing sequence of primes chosen to disperse hash
3405 /// codes across buckets as uniformly as possible. Throw a
3406 /// `std::length_error` exception if `n` is greater than the last prime number in the sequence.
3407 ///
3408 /// \note Note that, typically, prime numbers in the
3409 /// sequence have increasing values that reflect a growth factor (e.g.,
3410 /// each value in the sequence may be, approximately, two times the
3411 /// preceding value).
3412 static size_t nextPrime(size_t n);
3413};
3414
3415 // ====================
3416 // class HashTable_Util
3417 // ====================
3418
3419/// This utility `struct` provide utilities for initializing and destroying
3420/// bucket lists in anchors that are managed by a `HashTable`. They cannot
3421/// migrate down to `bslalg::HashTableImpUtil` as they rely on the standard
3422/// library @ref bslma_allocatortraits for their implementation.
3423///
3424/// See @ref bslstl_hashtable_cpp03
3425struct HashTable_Util {
3426
3427 // CLASS METHODS
3428
3429 /// Assert that the passed argument (the specified `ptr`) is not a null pointer value.
3430 ///
3431 /// \note Note that this utility is necessary as the
3432 /// `HashTable` class template may be instantiated with function
3433 /// pointers for the hasher or comparator policies, but there is no easy
3434 /// way to assert in general that the value of a generic type passed to
3435 /// a function is not a null pointer value.
3436 template <class TYPE>
3437 static void assertNotNullPointer(TYPE&);
3438 template <class TYPE>
3439 static void assertNotNullPointer(TYPE * const& ptr);
3440 template <class TYPE>
3441 static void assertNotNullPointer(TYPE * & ptr);
3442
3443 /// Destroy the specified `data` array of the specified length
3444 /// `bucketArraySize`, that was allocated by the specified `allocator`.
3445 template<class ALLOCATOR>
3447 std::size_t bucketArraySize,
3448 const ALLOCATOR& allocator);
3449
3450 /// Load into the specified `anchor` a (contiguous) array of buckets of
3451 /// the specified `bucketArraySize` using memory supplied by the specified `allocator`.
3452 ///
3453 /// \pre The behavior is undefined unless
3454 /// `0 < bucketArraySize` and `0 == anchor->bucketArraySize()`.
3455 ///
3456 /// \note Note that this operation has no effect on `anchor->listRootAddress()`.
3457 template<class ALLOCATOR>
3458 static void initAnchor(bslalg::HashTableAnchor *anchor,
3459 std::size_t bucketArraySize,
3460 const ALLOCATOR& allocator);
3461};
3462
3463 // ==============================
3464 // class HashTable_ImplParameters
3465 // ==============================
3466
3467 // It looks like the 'CallableVariable' adaptation would be more
3468 // appropriately addressed as part of the 'bslalg::FunctorAdapter' wrapper
3469 // than intrusively in this component, and in similar ways by any other
3470 // container trying to support the full range of standard conforming
3471 // functors. Given that our intent is to support standard predicates, it
3472 // may be appropriate to handle calling non-'const' 'operator()' overloads
3473 // (via a 'mutable' member) too.
3474
3475template <class HASHER>
3476struct HashTable_BaseHasher
3477 : bslalg::FunctorAdapter<HashTable_HashWrapper<
3478 typename CallableVariable<HASHER>::type> >
3479{
3480};
3481
3482template <class COMPARATOR>
3483struct HashTable_Comparator
3484 : bslalg::FunctorAdapter<HashTable_ComparatorWrapper<
3485 typename CallableVariable<COMPARATOR>::type> >
3486{
3487};
3488
3489/// This class holds all the parameterized parts of a `HashTable` class,
3490/// efficiently exploiting the empty base optimization without adding
3491/// unforeseen namespace associations to the `HashTable` class itself due to
3492/// the structural inheritance.
3493template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
3494class HashTable_ImplParameters
3495 : private HashTable_BaseHasher<HASHER>::Type
3496 , private HashTable_Comparator<COMPARATOR>::Type
3497{
3498
3499 // PRIVATE TYPES
3500 typedef typename HashTable_BaseHasher<HASHER>::Type BaseHasher;
3501 typedef typename HashTable_Comparator<COMPARATOR>::Type BaseComparator;
3502
3503 /// This typedef is a convenient alias for the utility associated with
3504 /// movable references.
3505 typedef bslmf::MovableRefUtil MoveUtil;
3506
3507 // typedefs stolen from HashTable
3508 typedef ALLOCATOR AllocatorType;
3509 typedef ::bsl::allocator_traits<AllocatorType> AllocatorTraits;
3510 typedef typename KEY_CONFIG::ValueType ValueType;
3511 typedef bslalg::BidirectionalNode<ValueType> NodeType;
3512
3513 public:
3514 // PUBLIC TYPES
3515 typedef HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR> HashTableType;
3516 typedef typename HashTableType::AllocatorTraits::
3517 template rebind_traits<NodeType> ReboundTraits;
3518 typedef typename ReboundTraits::allocator_type NodeAllocator;
3519
3520 typedef
3521 BidirectionalNodePool<typename HashTableType::ValueType, NodeAllocator>
3523
3524 private:
3525 // DATA
3526 NodeFactory d_nodeFactory; // nested 'struct's have public data by
3527 // convention, but should always be
3528 // accessed through the public methods.
3529
3530 private:
3531 // NOT IMPLEMENTED
3532
3533 /// = delete;
3534 HashTable_ImplParameters(const HashTable_ImplParameters&); // = delete;
3535 HashTable_ImplParameters& operator=(const HashTable_ImplParameters&);
3536
3537 public:
3538 // CREATORS
3539
3540 /// Create a `HashTable_ImplParameters` object having default
3541 /// constructed `HASHER` and `COMPARATOR` functors, and using the
3542 /// specified `allocator` to provide a `BidirectionalNodePool`.
3543 explicit HashTable_ImplParameters(const ALLOCATOR& allocator);
3544
3545 /// Create a `HashTable_ImplParameters` object having the specified
3546 /// `hash` and `compare` functors, and using the specified `allocator`
3547 /// to provide a `BidirectionalNodePool`.
3548 HashTable_ImplParameters(const HASHER& hash,
3549 const COMPARATOR& compare,
3550 const ALLOCATOR& allocator);
3551
3552 /// Create a `HashTable_ImplParameters` object having the same `hasher`
3553 /// and `comparator` attributes as the specified `original`, and
3554 /// providing a `BidirectionalNodePool` using the specified `allocator`.
3555 HashTable_ImplParameters(const HashTable_ImplParameters& original,
3556 const ALLOCATOR& allocator);
3557
3558 /// Create a `HashTable_ImplParameters` object with a copy of the
3559 /// `hasher` and `comparator` attributes associated with the specified
3560 /// `original` parameters object, and adopting all outstanding memory
3561 /// allocations and the allocator associated with `original`.
3562 ///
3563 /// \note Note that `original` is left in a valid but unspecified state.
3564 HashTable_ImplParameters(
3566
3567 // MANIPULATORS
3568
3569 /// Return a reference offering modifiable access to the `nodeFactory`
3570 /// owned by this object.
3572
3573 /// Efficiently exchange the value, functor, and allocator of this
3574 /// object with those of the specified `other` object. This method
3575 /// provides the no-throw exception-safety guarantee.
3576 void quickSwapExchangeAllocators(HashTable_ImplParameters *other);
3577
3578 /// Efficiently exchange the value and functors this object with those
3579 /// of the specified `other` object. This method provides the no-throw exception-safety guarantee.
3580 ///
3581 /// \pre The behavior is undefined unless this
3582 /// object was created with the same allocator as `other`.
3583 void quickSwapRetainAllocators(HashTable_ImplParameters *other);
3584
3585 // ACCESSORS
3586
3587 /// Return a reference offering non-modifiable access to the
3588 /// `comparator` functor owned by this object.
3589 const BaseComparator& comparator() const;
3590
3591 /// Return the hash code for the specified `key` using a copy of the hash functor supplied at construction.
3592 ///
3593 /// \note Note that this function is
3594 /// provided as a common way to resolve `const_cast` issues in the case
3595 /// that the stored hash functor has a function call operator that is
3596 /// not declared as `const`.
3597 template <class DEDUCED_KEY>
3598 std::size_t hashCodeForKey(DEDUCED_KEY& key) const;
3599
3600 /// Return the hash code for the specified `key` using a copy of the hash functor supplied at construction.
3601 ///
3602 /// \note Note that this function is
3603 /// provided as a common way to resolve `const_cast` issues in the case
3604 /// that the stored hash functor has a function call operator that is
3605 /// not declared as `const`.
3606 template <class LOOKUP_KEY>
3607 typename bsl::enable_if<
3608 BloombergLP::bslmf::IsTransparentPredicate<HASHER, LOOKUP_KEY>::value,
3609 std::size_t>::type
3610 hashCodeForTransparentKey(const LOOKUP_KEY &key) const {
3611 return originalHasher()(key);
3612 }
3613
3614 /// Return a reference offering non-modifiable access to the `hasher`
3615 /// functor owned by this object.
3616 const BaseHasher& hasher() const;
3617
3618 /// Return a reference offering non-modifiable access to the
3619 /// `nodeFactory` owned by this object.
3620 const NodeFactory& nodeFactory() const;
3621
3622 /// Return a reference offering non-modifiable access to the
3623 /// `comparator` functor owned by this object.
3624 const COMPARATOR& originalComparator() const;
3625
3626 /// Return a reference offering non-modifiable access to the `hasher`
3627 /// functor owned by this object.
3628 const HASHER& originalHasher() const;
3629};
3630
3631// ============================================================================
3632// TEMPLATE AND INLINE FUNCTION DEFINITIONS
3633// ============================================================================
3634
3635 // ---------------------------
3636 // class HashTable_HashWrapper
3637 // ---------------------------
3638
3639template <class FUNCTOR>
3640inline
3642: d_functor()
3643{
3644}
3645
3646template <class FUNCTOR>
3647inline
3648HashTable_HashWrapper<FUNCTOR>::HashTable_HashWrapper(const FUNCTOR& fn)
3649: d_functor(fn)
3650{
3651}
3652
3653template <class FUNCTOR>
3654template <class ARG_TYPE>
3655inline
3656std::size_t
3657HashTable_HashWrapper<FUNCTOR>::operator()(ARG_TYPE& arg) const
3658{
3659 return d_functor(arg);
3660}
3661
3662template <class FUNCTOR>
3663inline
3664const FUNCTOR& HashTable_HashWrapper<FUNCTOR>::functor() const
3665{
3666 return d_functor;
3667}
3668
3669template <class FUNCTOR>
3670inline
3671void HashTable_HashWrapper<FUNCTOR>::swap(HashTable_HashWrapper &other)
3672{
3673 using std::swap;
3674 swap(d_functor, other.d_functor);
3675}
3676
3677 // 'const FUNCTOR' partial specialization
3678
3679template <class FUNCTOR>
3680inline
3681HashTable_HashWrapper<const FUNCTOR>::HashTable_HashWrapper()
3682: d_functor()
3683{
3684}
3685
3686template <class FUNCTOR>
3687inline
3688HashTable_HashWrapper<const FUNCTOR>::HashTable_HashWrapper(const FUNCTOR& fn)
3689: d_functor(fn)
3690{
3691}
3692
3693template <class FUNCTOR>
3694template <class ARG_TYPE>
3695inline
3696std::size_t
3697HashTable_HashWrapper<const FUNCTOR>::operator()(ARG_TYPE& arg) const
3698{
3699 return d_functor(arg);
3700}
3701
3702template <class FUNCTOR>
3703inline
3704const FUNCTOR& HashTable_HashWrapper<const FUNCTOR>::functor() const
3705{
3706 return d_functor;
3707}
3708
3709 // 'FUNCTOR &' partial specialization
3710
3711template <class FUNCTOR>
3712inline
3713HashTable_HashWrapper<FUNCTOR &>::HashTable_HashWrapper(FUNCTOR& fn)
3714: d_functor(fn)
3715{
3716}
3717
3718template <class FUNCTOR>
3719template <class ARG_TYPE>
3720inline
3721std::size_t
3722HashTable_HashWrapper<FUNCTOR &>::operator()(ARG_TYPE& arg) const
3723{
3724 return d_functor(arg);
3725}
3726
3727template <class FUNCTOR>
3728inline
3729FUNCTOR& HashTable_HashWrapper<FUNCTOR &>::functor() const
3730{
3731 return d_functor;
3732}
3733
3734 // ---------------------------------
3735 // class HashTable_ComparatorWrapper
3736 // ---------------------------------
3737
3738template <class FUNCTOR>
3739inline
3740HashTable_ComparatorWrapper<FUNCTOR>::HashTable_ComparatorWrapper()
3741: d_functor()
3742{
3743}
3744
3745template <class FUNCTOR>
3746inline
3747HashTable_ComparatorWrapper<FUNCTOR>::
3748HashTable_ComparatorWrapper(const FUNCTOR& fn)
3749: d_functor(fn)
3750{
3751}
3752
3753template <class FUNCTOR>
3754template <class ARG1_TYPE, class ARG2_TYPE>
3755inline
3756bool
3757HashTable_ComparatorWrapper<FUNCTOR>::operator()(ARG1_TYPE& arg1,
3758 ARG2_TYPE& arg2) const
3759{
3760 return d_functor(arg1, arg2);
3761}
3762
3763template <class FUNCTOR>
3764const FUNCTOR& HashTable_ComparatorWrapper<FUNCTOR>::functor() const
3765{
3766 return d_functor;
3767}
3768
3769template <class FUNCTOR>
3770inline
3771void
3772HashTable_ComparatorWrapper<FUNCTOR>::swap(HashTable_ComparatorWrapper &other)
3773{
3774 using std::swap;
3775 swap(d_functor, other.d_functor);
3776}
3777
3778 // 'const FUNCTOR' partial specialization
3779
3780template <class FUNCTOR>
3781inline
3782HashTable_ComparatorWrapper<const FUNCTOR>::HashTable_ComparatorWrapper()
3783: d_functor()
3784{
3785}
3786
3787template <class FUNCTOR>
3788inline
3789HashTable_ComparatorWrapper<const FUNCTOR>::
3790HashTable_ComparatorWrapper(const FUNCTOR& fn)
3791: d_functor(fn)
3792{
3793}
3794
3795template <class FUNCTOR>
3796template <class ARG1_TYPE, class ARG2_TYPE>
3797inline
3798bool
3799HashTable_ComparatorWrapper<const FUNCTOR>::operator()(ARG1_TYPE& arg1,
3800 ARG2_TYPE& arg2) const
3801{
3802 return d_functor(arg1, arg2);
3803}
3804
3805template <class FUNCTOR>
3806const FUNCTOR& HashTable_ComparatorWrapper<const FUNCTOR>::functor() const
3807{
3808 return d_functor;
3809}
3810
3811 // 'FUNCTOR &' partial specialization
3812
3813template <class FUNCTOR>
3814inline
3815HashTable_ComparatorWrapper<FUNCTOR &>::
3816HashTable_ComparatorWrapper(FUNCTOR& fn)
3817: d_functor(fn)
3818{
3819}
3820
3821template <class FUNCTOR>
3822template <class ARG1_TYPE, class ARG2_TYPE>
3823inline
3824bool
3825HashTable_ComparatorWrapper<FUNCTOR &>::operator()(ARG1_TYPE& arg1,
3826 ARG2_TYPE& arg2) const
3827{
3828 return d_functor(arg1, arg2);
3829}
3830
3831template <class FUNCTOR>
3832inline
3833FUNCTOR& HashTable_ComparatorWrapper<FUNCTOR &>::functor() const
3834{
3835 return d_functor;
3836}
3837
3838 // ---------------------------
3839 // class HashTable_NodeProctor
3840 // ---------------------------
3841
3842// CREATORS
3843template <class FACTORY>
3844inline
3845HashTable_NodeProctor<FACTORY>::HashTable_NodeProctor(
3846 FACTORY *factory,
3848: d_factory_p(factory)
3849, d_node_p(node)
3850{
3851 BSLS_ASSERT_SAFE(factory);
3852}
3853
3854template <class FACTORY>
3855inline
3856HashTable_NodeProctor<FACTORY>::~HashTable_NodeProctor()
3857{
3858 if (d_node_p) {
3859 d_factory_p->deleteNode(d_node_p);
3860 }
3861}
3862
3863// MANIPULATORS
3864template <class FACTORY>
3865inline
3866void HashTable_NodeProctor<FACTORY>::release()
3867{
3868 d_node_p = 0;
3869}
3870
3871 // ----------------------------
3872 // class HashTable_ArrayProctor
3873 // ----------------------------
3874
3875// CREATORS
3876template <class FACTORY>
3877inline
3878HashTable_ArrayProctor<FACTORY>::HashTable_ArrayProctor(
3879 FACTORY *factory,
3881: d_factory_p(factory)
3882, d_anchor_p(anchor)
3883{
3884 BSLS_ASSERT_SAFE(factory);
3885 BSLS_ASSERT_SAFE(anchor);
3886}
3887
3888template <class FACTORY>
3889inline
3890HashTable_ArrayProctor<FACTORY>::~HashTable_ArrayProctor()
3891{
3892 if (d_anchor_p) {
3893 HashTable_Util::destroyBucketArray(d_anchor_p->bucketArrayAddress(),
3894 d_anchor_p->bucketArraySize(),
3895 d_factory_p->allocator());
3896
3897 bslalg::BidirectionalLink *root = d_anchor_p->listRootAddress();
3898 while (root) {
3899 bslalg::BidirectionalLink *next = root->nextLink();
3900 d_factory_p->deleteNode(root);
3901 root = next;
3902 }
3903 }
3904}
3905
3906// MANIPULATORS
3907template <class FACTORY>
3908inline
3909void HashTable_ArrayProctor<FACTORY>::release()
3910{
3911 d_anchor_p = 0;
3912}
3913
3914 // --------------------
3915 // class HashTable_Util
3916 // --------------------
3917
3918template <class TYPE>
3919inline
3920void HashTable_Util::assertNotNullPointer(TYPE&)
3921{
3922}
3923
3924template <class TYPE>
3925inline
3926void HashTable_Util::assertNotNullPointer(TYPE * const& ptr)
3927{
3928 // silence "unused parameter" warning in release builds:
3929 (void) ptr;
3930 BSLS_ASSERT(ptr);
3931}
3932
3933template <class TYPE>
3934inline
3935void HashTable_Util::assertNotNullPointer(TYPE * & ptr)
3936{
3937 // silence "unused parameter" warning in release builds:
3938 (void) ptr;
3939 BSLS_ASSERT(ptr);
3940}
3941
3942template <class ALLOCATOR>
3943inline
3944void HashTable_Util::destroyBucketArray(
3946 std::size_t bucketArraySize,
3947 const ALLOCATOR& allocator)
3948{
3949 BSLS_ASSERT_SAFE(data);
3951 (1 < bucketArraySize
3952 && HashTable_ImpDetails::defaultBucketAddress() != data)
3953 || (1 == bucketArraySize
3954 && HashTable_ImpDetails::defaultBucketAddress() == data));
3955
3956#ifdef BSLS_ASSERT_SAFE_IS_ACTIVE
3957 typedef typename bsl::allocator_traits<ALLOCATOR>::size_type AllocSizeType;
3959 bucketArraySize <= std::numeric_limits<AllocSizeType>::max());
3960#endif
3961
3962 if (HashTable_ImpDetails::defaultBucketAddress() != data) {
3964 bucketArraySize);
3965 }
3966}
3967
3968template <class ALLOCATOR>
3969inline
3970void HashTable_Util::initAnchor(bslalg::HashTableAnchor *anchor,
3971 std::size_t bucketArraySize,
3972 const ALLOCATOR& allocator)
3973{
3974 BSLS_ASSERT_SAFE(anchor);
3975 BSLS_ASSERT_SAFE(0 != bucketArraySize);
3976
3977#ifdef BSLS_ASSERT_SAFE_IS_ACTIVE
3978 typedef typename bsl::allocator_traits<ALLOCATOR>::size_type AllocSizeType;
3980 bucketArraySize <= std::numeric_limits<AllocSizeType>::max());
3981#endif
3982
3983 typedef bslalg::HashTableBucket Bucket;
3984 Bucket *data = bslma::AllocatorUtil::allocateObject<Bucket>(allocator,
3985 bucketArraySize);
3986
3987 std::fill_n(data, bucketArraySize, Bucket());
3988
3989 anchor->setBucketArrayAddressAndSize(data, bucketArraySize);
3990}
3991
3992 //-------------------------------
3993 // class HashTable_ImplParameters
3994 //-------------------------------
3995
3996// CREATORS
3997template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
3998inline
3999HashTable_ImplParameters<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4000HashTable_ImplParameters(const ALLOCATOR& allocator)
4001: BaseHasher()
4002, BaseComparator()
4003, d_nodeFactory(allocator)
4004{
4005}
4006
4007template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4008inline
4009HashTable_ImplParameters<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4010HashTable_ImplParameters(const HASHER& hash,
4011 const COMPARATOR& compare,
4012 const ALLOCATOR& allocator)
4013: BaseHasher(hash)
4014, BaseComparator(compare)
4015, d_nodeFactory(allocator)
4016{
4017}
4018
4019template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4020inline
4021HashTable_ImplParameters<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4022HashTable_ImplParameters(const HashTable_ImplParameters& original,
4023 const ALLOCATOR& allocator)
4024: BaseHasher(static_cast<const BaseHasher&>(original))
4025, BaseComparator(static_cast<const BaseComparator&>(original))
4026, d_nodeFactory(allocator)
4027{
4028}
4029
4030template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4031inline
4032HashTable_ImplParameters<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4033HashTable_ImplParameters(bslmf::MovableRef<HashTable_ImplParameters> original)
4034: BaseHasher(static_cast<const BaseHasher&>(original))
4035, BaseComparator(static_cast<const BaseComparator&>(original))
4036, d_nodeFactory(MoveUtil::move(MoveUtil::access(original).d_nodeFactory))
4037{
4038}
4039
4040// MANIPULATORS
4041template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4042inline
4043typename HashTable_ImplParameters<KEY_CONFIG,
4044 HASHER,
4045 COMPARATOR,
4046 ALLOCATOR>::NodeFactory &
4047HashTable_ImplParameters<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4048nodeFactory()
4049{
4050 return d_nodeFactory;
4051}
4052
4053template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4054inline
4055void HashTable_ImplParameters<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4056quickSwapExchangeAllocators(HashTable_ImplParameters *other)
4057{
4058 BSLS_ASSERT_SAFE(other);
4059
4060 using std::swap;
4061 swap(*static_cast<BaseHasher*>(this), *static_cast<BaseHasher*>(other));
4062
4063 swap(*static_cast<BaseComparator*>(this),
4064 *static_cast<BaseComparator*>(other));
4065
4066 nodeFactory().swapExchangeAllocators(other->nodeFactory());
4067}
4068
4069template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4070inline
4071void HashTable_ImplParameters<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4072quickSwapRetainAllocators(HashTable_ImplParameters *other)
4073{
4074 BSLS_ASSERT_SAFE(other);
4075
4076 using std::swap;
4077 swap(*static_cast<BaseHasher*>(this), *static_cast<BaseHasher*>(other));
4078
4079 swap(*static_cast<BaseComparator*>(this),
4080 *static_cast<BaseComparator*>(other));
4081
4082 nodeFactory().swapRetainAllocators(other->nodeFactory());
4083}
4084
4085// ACCESSORS
4086template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4087inline
4088const typename HashTable_ImplParameters<KEY_CONFIG,
4089 HASHER,
4090 COMPARATOR,
4091 ALLOCATOR>::BaseComparator &
4092HashTable_ImplParameters<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4093comparator() const
4094{
4095 return *this;
4096}
4097
4098template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4099template <class DEDUCED_KEY>
4100inline
4101std::size_t HashTable_ImplParameters<KEY_CONFIG,
4102 HASHER,
4103 COMPARATOR,
4104 ALLOCATOR>::
4105hashCodeForKey(DEDUCED_KEY& key) const
4106{
4107 return static_cast<const BaseHasher &>(*this)(key);
4108}
4109
4110template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4111inline
4112const typename HashTable_ImplParameters<KEY_CONFIG,
4113 HASHER,
4114 COMPARATOR,
4115 ALLOCATOR>::BaseHasher &
4116HashTable_ImplParameters<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::hasher()
4117 const
4118{
4119 return *this;
4120}
4121
4122template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4123inline
4124const typename HashTable_ImplParameters<KEY_CONFIG,
4125 HASHER,
4126 COMPARATOR,
4127 ALLOCATOR>::NodeFactory &
4128HashTable_ImplParameters<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4129nodeFactory() const
4130{
4131 return d_nodeFactory;
4132}
4133
4134template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4135inline
4136const COMPARATOR&
4137HashTable_ImplParameters<KEY_CONFIG,
4138 HASHER,
4139 COMPARATOR,
4140 ALLOCATOR>::originalComparator() const
4141{
4142 return static_cast<const BaseComparator *>(this)->functor();
4143}
4144
4145template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4146inline
4147const HASHER& HashTable_ImplParameters<KEY_CONFIG,
4148 HASHER,
4149 COMPARATOR,
4150 ALLOCATOR>::originalHasher() const
4151{
4152 return static_cast<const BaseHasher *>(this)->functor();
4153}
4154
4155 //----------------
4156 // class HashTable
4157 //----------------
4158
4159// CREATORS
4160template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4161inline
4162HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4163HashTable(const ALLOCATOR& basicAllocator)
4164: d_parameters(basicAllocator)
4165, d_anchor(HashTable_ImpDetails::defaultBucketAddress(), 1, 0)
4166, d_size()
4167, d_capacity()
4168, d_maxLoadFactor(1.0)
4169{
4172}
4173
4174template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4175inline
4176HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4177HashTable(const HASHER& hash,
4178 const COMPARATOR& compare,
4179 SizeType initialNumBuckets,
4180 float initialMaxLoadFactor,
4181 const ALLOCATOR& basicAllocator)
4182: d_parameters(hash, compare, basicAllocator)
4183, d_anchor(HashTable_ImpDetails::defaultBucketAddress(), 1, 0)
4184, d_size()
4185, d_capacity(0)
4186, d_maxLoadFactor(initialMaxLoadFactor)
4187{
4188 BSLS_ASSERT_SAFE(0.0f < initialMaxLoadFactor);
4189
4191 HashTable_Util::assertNotNullPointer(hash);
4192 }
4194 HashTable_Util::assertNotNullPointer(compare);
4195 }
4196
4197 if (0 != initialNumBuckets) {
4198 size_t capacity; // This may be a different type than SizeType.
4199 size_t numBuckets = HashTable_ImpDetails::growBucketsForLoadFactor(
4200 &capacity,
4201 1,
4202 static_cast<size_t>(initialNumBuckets),
4203 d_maxLoadFactor);
4204 HashTable_Util::initAnchor(&d_anchor, numBuckets, basicAllocator);
4205 d_capacity = static_cast<SizeType>(capacity);
4206 }
4207}
4208
4209template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4210inline
4211HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4212HashTable(const HashTable& original)
4213: d_parameters(
4214 original.d_parameters,
4215 AllocatorTraits::select_on_container_copy_construction(original.allocator()))
4216, d_anchor(HashTable_ImpDetails::defaultBucketAddress(), 1, 0)
4217, d_size(original.d_size)
4218, d_capacity(0)
4219, d_maxLoadFactor(original.d_maxLoadFactor)
4220{
4221 if (0 < d_size) {
4222 d_parameters.nodeFactory().reserveNodes(original.d_size);
4223 this->copyDataStructure(original.d_anchor.listRootAddress());
4224 }
4225}
4226
4227template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4228inline
4229HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::HashTable(
4230 BloombergLP::bslmf::MovableRef<HashTable> original)
4231: d_parameters(MoveUtil::move(MoveUtil::access(original).d_parameters))
4232, d_anchor(HashTable_ImpDetails::defaultBucketAddress(), 1, 0)
4233, d_size()
4234, d_capacity()
4235, d_maxLoadFactor(1.0)
4236{
4237 HashTable& lvalue = original;
4238 using std::swap;
4239 swap(d_anchor, lvalue.d_anchor);
4240 swap(d_size, lvalue.d_size);
4241 swap(d_capacity, lvalue.d_capacity);
4242 swap(d_maxLoadFactor, lvalue.d_maxLoadFactor);
4243}
4244
4245template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4246inline
4247HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4248HashTable(const HashTable& original, const ALLOCATOR& basicAllocator)
4249: d_parameters(original.d_parameters, basicAllocator)
4250, d_anchor(HashTable_ImpDetails::defaultBucketAddress(), 1, 0)
4251, d_size(original.d_size)
4252, d_capacity(0)
4253, d_maxLoadFactor(original.d_maxLoadFactor)
4254{
4255 if (0 < d_size) {
4256 d_parameters.nodeFactory().reserveNodes(original.d_size);
4257 this->copyDataStructure(original.d_anchor.listRootAddress());
4258 }
4259}
4260
4261template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4262HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4263HashTable(bslmf::MovableRef<HashTable> original,
4264 const ALLOCATOR& basicAllocator)
4265: d_parameters(MoveUtil::access(original).d_parameters.originalHasher(),
4266 MoveUtil::access(original).d_parameters.originalComparator(),
4267 basicAllocator)
4268, d_anchor(HashTable_ImpDetails::defaultBucketAddress(), 1, 0)
4269, d_size()
4270, d_capacity()
4271, d_maxLoadFactor(1.0)
4272{
4273 HashTable& lvalue = original;
4275 basicAllocator == lvalue.allocator())) {
4276 d_parameters.nodeFactory().adopt(
4277 MoveUtil::move(lvalue.d_parameters.nodeFactory()));
4278 using std::swap;
4279 swap(d_anchor, lvalue.d_anchor);
4280 swap(d_size, lvalue.d_size);
4281 swap(d_capacity, lvalue.d_capacity);
4282 swap(d_maxLoadFactor, lvalue.d_maxLoadFactor);
4283 }
4284 else {
4285 d_size = lvalue.d_size;
4286 d_maxLoadFactor = lvalue.d_maxLoadFactor;
4287 if (0 < d_size) {
4288 // 'original' left in the default state
4290 HashTable_ImpDetails::defaultBucketAddress(), 1, 0);
4291 using std::swap;
4292 swap(anchor, lvalue.d_anchor);
4293
4294 lvalue.d_size = 0;
4295 lvalue.d_capacity = 0;
4296 lvalue.d_maxLoadFactor = 1.0f;
4297
4298 HashTable_ArrayProctor<typename ImplParameters::NodeFactory>
4299 arrayProctor(&lvalue.d_parameters.nodeFactory(),
4300 &anchor);
4301
4302 d_parameters.nodeFactory().reserveNodes(d_size);
4303 this->moveDataStructure(anchor.listRootAddress());
4304
4305 // 'arrayProctor' will care of deleting the nodes
4306 }
4307 }
4308}
4309
4310template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4311inline
4312HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::~HashTable()
4313{
4314#if defined(BDE_BUILD_TARGET_SAFE_2)
4315 // ASSERT class invariant only in SAFE_2 builds. Note that we specifically
4316 // use the MallocFree allocator, rather than allowing the default allocator
4317 // to supply memory to this state-checking function, in case the object
4318 // allocator *is* the default allocator, and so may be restricted during
4319 // testing. This would cause the test below to fail by throwing a bad
4320 // allocation exception, and so result in a throwing destructor. While the
4321 // MallocFree allocator might also run out of resources, that is not the
4322 // kind of catastrophic failure we are concerned with handling in an
4323 // invariant check that runs only in SAFE_2 builds from a destructor.
4324
4325 BSLS_ASSERT_SAFE(bslalg::HashTableImpUtil::isWellFormed<KEY_CONFIG>(
4326 this->d_anchor,
4327 this->d_parameters.hasher(),
4328 HashTable_ImpDetails::incidentalAllocator()));
4329#endif
4330
4331 this->removeAllAndDeallocate();
4332}
4333
4334// PRIVATE MANIPULATORS
4335template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4336void
4337HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::copyDataStructure(
4339{
4340 BSLS_ASSERT(0 != cursor);
4341 BSLS_ASSERT(0 < d_size);
4342
4343 // This function will completely replace 'this->d_anchor's state. It is
4344 // the caller's responsibility to ensure this will not leak resources owned
4345 // only by the previous state, such as the linked list.
4346
4347 // Allocate an appropriate number of buckets
4348
4349 size_t capacity;
4350 size_t numBuckets = HashTable_ImpDetails::growBucketsForLoadFactor(
4351 &capacity,
4352 static_cast<size_t>(d_size),
4353 2,
4354 d_maxLoadFactor);
4355
4356 d_anchor.setListRootAddress(0);
4357 HashTable_Util::initAnchor(&d_anchor, numBuckets, this->allocator());
4358
4359 // create a proctor for d_anchor's allocated array, and the list to follow.
4360
4361 HashTable_ArrayProctor<typename ImplParameters::NodeFactory>
4362 arrayProctor(&d_parameters.nodeFactory(), &d_anchor);
4363
4364 d_capacity = static_cast<SizeType>(capacity);
4365
4366 do {
4367 // Computing hash code depends on user-supplied code, and may throw.
4368 // Therefore, obtain the hash code from the node we are about to copy,
4369 // before any memory is allocated, so there is no risk of leaking an
4370 // object. The hash code must be the same for both elements.
4371
4372 size_t hashCode = this->hashCodeForNode(cursor);
4373 bslalg::BidirectionalLink *newNode =
4374 d_parameters.nodeFactory().cloneNode(*cursor);
4375
4377 newNode,
4378 hashCode);
4379 }
4380 while (0 != (cursor = cursor->nextLink()));
4381
4382 // release the proctor
4383
4384 arrayProctor.release();
4385}
4386
4387template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4388void
4389HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::moveDataStructure(
4391{
4392 BSLS_ASSERT(0 != cursor);
4393 BSLS_ASSERT(0 < d_size);
4394
4395 // This function will completely replace 'this->d_anchor's state. It is
4396 // the caller's responsibility to ensure this will not leak resources owned
4397 // only by the previous state, such as the linked list.
4398
4399 // Allocate an appropriate number of buckets
4400
4401 size_t capacity;
4402 size_t numBuckets = HashTable_ImpDetails::growBucketsForLoadFactor(
4403 &capacity,
4404 static_cast<size_t>(d_size),
4405 2,
4406 d_maxLoadFactor);
4407
4408 d_anchor.setListRootAddress(0);
4409 HashTable_Util::initAnchor(&d_anchor, numBuckets, this->allocator());
4410
4411 d_capacity = static_cast<SizeType>(capacity);
4412
4413 // create a proctor for d_anchor's allocated array, and the list to follow.
4414
4415 HashTable_ArrayProctor<typename ImplParameters::NodeFactory>
4416 arrayProctor(&d_parameters.nodeFactory(), &d_anchor);
4417
4418 do {
4419 // Computing hash code depends on user-supplied code, and may throw.
4420 // Therefore, obtain the hash code from the node we are about to copy,
4421 // before any memory is allocated, so there is no risk of leaking an
4422 // object. The hash code must be the same for both elements.
4423
4424 size_t hashCode = this->hashCodeForNode(cursor);
4425 bslalg::BidirectionalLink *newNode =
4426 d_parameters.nodeFactory().moveIntoNewNode(cursor);
4427
4429 newNode,
4430 hashCode);
4431 }
4432 while (0 != (cursor = cursor->nextLink()));
4433
4434 // release the proctor
4435
4436 arrayProctor.release();
4437}
4438
4439template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4440void
4441HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4442quickSwapExchangeAllocators(HashTable *other)
4443{
4444 BSLS_ASSERT_SAFE(other);
4445
4446 d_parameters.quickSwapExchangeAllocators(&other->d_parameters);
4447
4448 using std::swap;
4449 swap(d_anchor, other->d_anchor);
4450 swap(d_size, other->d_size);
4451 swap(d_capacity, other->d_capacity);
4452 swap(d_maxLoadFactor, other->d_maxLoadFactor);
4453}
4454
4455template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4456void
4457HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4458quickSwapRetainAllocators(HashTable *other)
4459{
4460 BSLS_ASSERT_SAFE(other);
4461 BSLS_ASSERT_SAFE(this->allocator() == other->allocator());
4462
4463 d_parameters.quickSwapRetainAllocators(&other->d_parameters);
4464
4465 using std::swap;
4466 swap(d_anchor, other->d_anchor);
4467 swap(d_size, other->d_size);
4468 swap(d_capacity, other->d_capacity);
4469 swap(d_maxLoadFactor, other->d_maxLoadFactor);
4470}
4471
4472template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4473void
4474HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
4475rehashIntoExactlyNumBuckets(SizeType newNumBuckets, SizeType capacity)
4476{
4477 /// An object of this proctor class guarantees that, if an exception is
4478 /// thrown by a user-supplied hash functor, the container remains in a
4479 /// valid, usable (but unspecified) state. In fact, that state will be
4480 /// empty, as there is no reliable way to re-index a bucket array if the
4481 /// hash functor is throwing, and the array is potentially corrupted
4482 /// following a failed ImpUtil::rehash call.
4483 ///
4484 /// See @ref bslstl_hashtable_cpp03
4485 class Proctor {
4486
4487 private:
4488 HashTable *d_table_p;
4489 bslalg::HashTableAnchor *d_originalAnchor_p;
4490 bslalg::HashTableAnchor *d_newAnchor_p;
4491
4492#if !defined(BSLS_PLATFORM_CMP_MSVC)
4493 // Microsoft warns if these methods are declared private.
4494
4495 private:
4496 // NOT IMPLEMENTED
4497 Proctor(const Proctor&); // = delete;
4498 Proctor& operator=(const Proctor&); // = delete;
4499#endif
4500
4501 public:
4502 // CREATORS
4503 Proctor(HashTable *table,
4504 bslalg::HashTableAnchor *originalAnchor,
4505 bslalg::HashTableAnchor *newAnchor)
4506 : d_table_p(table)
4507 , d_originalAnchor_p(originalAnchor)
4508 , d_newAnchor_p(newAnchor)
4509 {
4510 BSLS_ASSERT_SAFE(table);
4511 BSLS_ASSERT_SAFE(originalAnchor);
4512 BSLS_ASSERT_SAFE(newAnchor);
4513 }
4514
4515 ~Proctor()
4516 {
4517 if (d_originalAnchor_p) {
4518 // Not dismissed, and the newAnchor now holds the correct
4519 // list-root.
4520
4521 d_originalAnchor_p->setListRootAddress(
4522 d_newAnchor_p->listRootAddress());
4523 d_table_p->removeAll();
4524 }
4525
4526 // Always destroy the spare anchor's bucket array at the end of
4527 // scope. On a non-exceptional run, this will effectively be the
4528 // original bucket-array, as the anchors are swapped.
4529
4530 HashTable_Util::destroyBucketArray(
4531 d_newAnchor_p->bucketArrayAddress(),
4532 d_newAnchor_p->bucketArraySize(),
4533 d_table_p->allocator());
4534 }
4535
4536 // MANIPULATORS
4537 void dismiss()
4538 {
4539 d_originalAnchor_p = 0;
4540 }
4541 };
4542
4543 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4544
4545 // Now that 'anchor' is not default constructible, we take a copy of the
4546 // anchor in the table. Would it be better for 'initAnchor' to be replaced
4547 // with a 'createArrayOfEmptyBuckets' function, and we use the result to
4548 // construct the 'newAnchor'?
4549
4550 bslalg::HashTableAnchor newAnchor(0, 0, 0);
4551 HashTable_Util::initAnchor(&newAnchor,
4552 static_cast<size_t>(newNumBuckets),
4553 this->allocator());
4554
4555 Proctor cleanUpIfUserHashThrows(this, &d_anchor, &newAnchor);
4556
4557 if (d_anchor.listRootAddress()) {
4558 bslalg::HashTableImpUtil::rehash<KEY_CONFIG>(
4559 &newAnchor,
4560 this->d_anchor.listRootAddress(),
4561 this->d_parameters.hasher());
4562 }
4563
4564 cleanUpIfUserHashThrows.dismiss();
4565
4566 d_anchor.swap(newAnchor);
4567 d_capacity = capacity;
4568}
4569
4570template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4571inline
4572void
4573HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::removeAllAndDeallocate()
4574{
4575 this->removeAllImp();
4576 HashTable_Util::destroyBucketArray(d_anchor.bucketArrayAddress(),
4577 d_anchor.bucketArraySize(),
4578 this->allocator());
4579}
4580
4581template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4582void
4583HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::removeAllImp()
4584{
4585 typedef bslalg::BidirectionalLink BidirectionalLink;
4586
4587 // Doing too much book-keeping of hash table - look for a more efficient
4588 // dispose-as-we-walk, that simply resets table.Anchor.next = 0, and
4589 // assigns the buckets index all null pointers
4590
4591 if (BidirectionalLink *root = d_anchor.listRootAddress()) {
4592 BidirectionalLink *next;
4593 do {
4594 next = root->nextLink();
4595 d_parameters.nodeFactory().deleteNode(
4596 static_cast<NodeType *>(root));
4597 }
4598 while(0 != (root = next));
4599 }
4600}
4601
4602// PRIVATE ACCESSORS
4603template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4604template <class DEDUCED_KEY>
4605inline
4607HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::find(
4608 DEDUCED_KEY& key,
4609 std::size_t hashValue) const
4610{
4611 return bslalg::HashTableImpUtil::find<KEY_CONFIG>(
4612 d_anchor,
4613 key,
4614 d_parameters.comparator(),
4615 hashValue);
4616}
4617
4618template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4619inline
4621HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::getBucketAddress(
4622 SizeType bucketIndex) const
4623{
4624 BSLS_ASSERT_SAFE(bucketIndex < this->numBuckets());
4625
4626 return d_anchor.bucketArrayAddress() + bucketIndex;
4627}
4628
4629template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4630inline
4631std::size_t
4632HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::hashCodeForNode(
4633 bslalg::BidirectionalLink *node) const
4634{
4635 BSLS_ASSERT_SAFE(node);
4636
4637 return d_parameters.hashCodeForKey(
4638 bslalg::HashTableImpUtil::extractKey<KEY_CONFIG>(node));
4639}
4640
4641// MANIPULATORS
4642template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4643inline
4644HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>&
4645HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::operator=(
4646 const HashTable& rhs)
4647{
4648 if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this != &rhs)) {
4649
4650 if (AllocatorTraits::propagate_on_container_copy_assignment::value) {
4651 HashTable other(rhs, rhs.allocator());
4652 quickSwapExchangeAllocators(&other);
4653 }
4654 else {
4655 HashTable other(rhs, this->allocator());
4656 quickSwapRetainAllocators(&other);
4657 }
4658 }
4659 return *this;
4660}
4661
4662template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4663inline
4664HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>&
4665HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::operator=(
4667{
4668 HashTable& lvalue = rhs;
4669 if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this != &lvalue)) {
4670 if (allocator() == lvalue.allocator()) {
4671 HashTable other(MoveUtil::move(lvalue));
4672 quickSwapRetainAllocators(&other);
4673 }
4674 else if (
4675 AllocatorTraits::propagate_on_container_move_assignment::value) {
4676 HashTable other(MoveUtil::move(lvalue));
4677 quickSwapExchangeAllocators(&other);
4678 }
4679 else {
4680 HashTable other(MoveUtil::move(lvalue), allocator());
4681 quickSwapRetainAllocators(&other);
4682 }
4683 }
4684 return *this;
4685}
4686
4687#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
4688// {{{ BEGIN GENERATED CODE
4689// Command line: sim_cpp11_features.pl bslstl_hashtable.h
4690#ifndef BSLSTL_HASHTABLE_VARIADIC_LIMIT
4691#define BSLSTL_HASHTABLE_VARIADIC_LIMIT 10
4692#endif
4693#ifndef BSLSTL_HASHTABLE_VARIADIC_LIMIT_E
4694#define BSLSTL_HASHTABLE_VARIADIC_LIMIT_E BSLSTL_HASHTABLE_VARIADIC_LIMIT
4695#endif
4696#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 0
4697template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4699HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplace(
4700 )
4701{
4702 typedef bslalg::HashTableImpUtil ImpUtil;
4703
4704
4705 if (d_size >= d_capacity) {
4706 this->rehashForNumBuckets(numBuckets() * 2);
4707 }
4708
4709
4710 bslalg::BidirectionalLink *newNode =
4711 d_parameters.nodeFactory().emplaceIntoNewNode(
4712 );
4713
4714
4715 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
4716 nodeProctor(&d_parameters.nodeFactory(), newNode);
4717
4718
4719 size_t hashCode = this->d_parameters.hashCodeForKey(
4720 ImpUtil::extractKey<KEY_CONFIG>(newNode));
4721 bslalg::BidirectionalLink *position = this->find(
4722 ImpUtil::extractKey<KEY_CONFIG>(newNode),
4723 hashCode);
4724
4725 if (!position) {
4726 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
4727 }
4728 else {
4729 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, position);
4730 }
4731 nodeProctor.release();
4732
4733 ++d_size;
4734
4735 return newNode;
4736}
4737#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 0
4738
4739#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 1
4740template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4741template <class ARGS_01>
4743HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplace(
4744 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01)
4745{
4746 typedef bslalg::HashTableImpUtil ImpUtil;
4747
4748
4749 if (d_size >= d_capacity) {
4750 this->rehashForNumBuckets(numBuckets() * 2);
4751 }
4752
4753
4754 bslalg::BidirectionalLink *newNode =
4755 d_parameters.nodeFactory().emplaceIntoNewNode(
4756 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01));
4757
4758
4759 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
4760 nodeProctor(&d_parameters.nodeFactory(), newNode);
4761
4762
4763 size_t hashCode = this->d_parameters.hashCodeForKey(
4764 ImpUtil::extractKey<KEY_CONFIG>(newNode));
4765 bslalg::BidirectionalLink *position = this->find(
4766 ImpUtil::extractKey<KEY_CONFIG>(newNode),
4767 hashCode);
4768
4769 if (!position) {
4770 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
4771 }
4772 else {
4773 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, position);
4774 }
4775 nodeProctor.release();
4776
4777 ++d_size;
4778
4779 return newNode;
4780}
4781#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 1
4782
4783#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 2
4784template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4785template <class ARGS_01,
4786 class ARGS_02>
4788HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplace(
4789 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
4790 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02)
4791{
4792 typedef bslalg::HashTableImpUtil ImpUtil;
4793
4794
4795 if (d_size >= d_capacity) {
4796 this->rehashForNumBuckets(numBuckets() * 2);
4797 }
4798
4799
4800 bslalg::BidirectionalLink *newNode =
4801 d_parameters.nodeFactory().emplaceIntoNewNode(
4802 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
4803 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02));
4804
4805
4806 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
4807 nodeProctor(&d_parameters.nodeFactory(), newNode);
4808
4809
4810 size_t hashCode = this->d_parameters.hashCodeForKey(
4811 ImpUtil::extractKey<KEY_CONFIG>(newNode));
4812 bslalg::BidirectionalLink *position = this->find(
4813 ImpUtil::extractKey<KEY_CONFIG>(newNode),
4814 hashCode);
4815
4816 if (!position) {
4817 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
4818 }
4819 else {
4820 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, position);
4821 }
4822 nodeProctor.release();
4823
4824 ++d_size;
4825
4826 return newNode;
4827}
4828#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 2
4829
4830#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 3
4831template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4832template <class ARGS_01,
4833 class ARGS_02,
4834 class ARGS_03>
4836HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplace(
4837 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
4838 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
4839 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03)
4840{
4841 typedef bslalg::HashTableImpUtil ImpUtil;
4842
4843
4844 if (d_size >= d_capacity) {
4845 this->rehashForNumBuckets(numBuckets() * 2);
4846 }
4847
4848
4849 bslalg::BidirectionalLink *newNode =
4850 d_parameters.nodeFactory().emplaceIntoNewNode(
4851 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
4852 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
4853 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03));
4854
4855
4856 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
4857 nodeProctor(&d_parameters.nodeFactory(), newNode);
4858
4859
4860 size_t hashCode = this->d_parameters.hashCodeForKey(
4861 ImpUtil::extractKey<KEY_CONFIG>(newNode));
4862 bslalg::BidirectionalLink *position = this->find(
4863 ImpUtil::extractKey<KEY_CONFIG>(newNode),
4864 hashCode);
4865
4866 if (!position) {
4867 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
4868 }
4869 else {
4870 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, position);
4871 }
4872 nodeProctor.release();
4873
4874 ++d_size;
4875
4876 return newNode;
4877}
4878#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 3
4879
4880#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 4
4881template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4882template <class ARGS_01,
4883 class ARGS_02,
4884 class ARGS_03,
4885 class ARGS_04>
4887HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplace(
4888 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
4889 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
4890 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
4891 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04)
4892{
4893 typedef bslalg::HashTableImpUtil ImpUtil;
4894
4895
4896 if (d_size >= d_capacity) {
4897 this->rehashForNumBuckets(numBuckets() * 2);
4898 }
4899
4900
4901 bslalg::BidirectionalLink *newNode =
4902 d_parameters.nodeFactory().emplaceIntoNewNode(
4903 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
4904 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
4905 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
4906 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04));
4907
4908
4909 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
4910 nodeProctor(&d_parameters.nodeFactory(), newNode);
4911
4912
4913 size_t hashCode = this->d_parameters.hashCodeForKey(
4914 ImpUtil::extractKey<KEY_CONFIG>(newNode));
4915 bslalg::BidirectionalLink *position = this->find(
4916 ImpUtil::extractKey<KEY_CONFIG>(newNode),
4917 hashCode);
4918
4919 if (!position) {
4920 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
4921 }
4922 else {
4923 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, position);
4924 }
4925 nodeProctor.release();
4926
4927 ++d_size;
4928
4929 return newNode;
4930}
4931#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 4
4932
4933#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 5
4934template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4935template <class ARGS_01,
4936 class ARGS_02,
4937 class ARGS_03,
4938 class ARGS_04,
4939 class ARGS_05>
4941HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplace(
4942 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
4943 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
4944 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
4945 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
4946 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05)
4947{
4948 typedef bslalg::HashTableImpUtil ImpUtil;
4949
4950
4951 if (d_size >= d_capacity) {
4952 this->rehashForNumBuckets(numBuckets() * 2);
4953 }
4954
4955
4956 bslalg::BidirectionalLink *newNode =
4957 d_parameters.nodeFactory().emplaceIntoNewNode(
4958 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
4959 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
4960 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
4961 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
4962 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05));
4963
4964
4965 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
4966 nodeProctor(&d_parameters.nodeFactory(), newNode);
4967
4968
4969 size_t hashCode = this->d_parameters.hashCodeForKey(
4970 ImpUtil::extractKey<KEY_CONFIG>(newNode));
4971 bslalg::BidirectionalLink *position = this->find(
4972 ImpUtil::extractKey<KEY_CONFIG>(newNode),
4973 hashCode);
4974
4975 if (!position) {
4976 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
4977 }
4978 else {
4979 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, position);
4980 }
4981 nodeProctor.release();
4982
4983 ++d_size;
4984
4985 return newNode;
4986}
4987#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 5
4988
4989#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 6
4990template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
4991template <class ARGS_01,
4992 class ARGS_02,
4993 class ARGS_03,
4994 class ARGS_04,
4995 class ARGS_05,
4996 class ARGS_06>
4998HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplace(
4999 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
5000 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
5001 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
5002 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
5003 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
5004 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06)
5005{
5006 typedef bslalg::HashTableImpUtil ImpUtil;
5007
5008
5009 if (d_size >= d_capacity) {
5010 this->rehashForNumBuckets(numBuckets() * 2);
5011 }
5012
5013
5014 bslalg::BidirectionalLink *newNode =
5015 d_parameters.nodeFactory().emplaceIntoNewNode(
5016 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
5017 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
5018 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
5019 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
5020 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
5021 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06));
5022
5023
5024 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5025 nodeProctor(&d_parameters.nodeFactory(), newNode);
5026
5027
5028 size_t hashCode = this->d_parameters.hashCodeForKey(
5029 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5030 bslalg::BidirectionalLink *position = this->find(
5031 ImpUtil::extractKey<KEY_CONFIG>(newNode),
5032 hashCode);
5033
5034 if (!position) {
5035 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5036 }
5037 else {
5038 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, position);
5039 }
5040 nodeProctor.release();
5041
5042 ++d_size;
5043
5044 return newNode;
5045}
5046#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 6
5047
5048#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 7
5049template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5050template <class ARGS_01,
5051 class ARGS_02,
5052 class ARGS_03,
5053 class ARGS_04,
5054 class ARGS_05,
5055 class ARGS_06,
5056 class ARGS_07>
5058HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplace(
5059 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
5060 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
5061 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
5062 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
5063 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
5064 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
5065 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07)
5066{
5067 typedef bslalg::HashTableImpUtil ImpUtil;
5068
5069
5070 if (d_size >= d_capacity) {
5071 this->rehashForNumBuckets(numBuckets() * 2);
5072 }
5073
5074
5075 bslalg::BidirectionalLink *newNode =
5076 d_parameters.nodeFactory().emplaceIntoNewNode(
5077 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
5078 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
5079 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
5080 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
5081 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
5082 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
5083 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07));
5084
5085
5086 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5087 nodeProctor(&d_parameters.nodeFactory(), newNode);
5088
5089
5090 size_t hashCode = this->d_parameters.hashCodeForKey(
5091 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5092 bslalg::BidirectionalLink *position = this->find(
5093 ImpUtil::extractKey<KEY_CONFIG>(newNode),
5094 hashCode);
5095
5096 if (!position) {
5097 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5098 }
5099 else {
5100 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, position);
5101 }
5102 nodeProctor.release();
5103
5104 ++d_size;
5105
5106 return newNode;
5107}
5108#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 7
5109
5110#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 8
5111template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5112template <class ARGS_01,
5113 class ARGS_02,
5114 class ARGS_03,
5115 class ARGS_04,
5116 class ARGS_05,
5117 class ARGS_06,
5118 class ARGS_07,
5119 class ARGS_08>
5121HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplace(
5122 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
5123 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
5124 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
5125 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
5126 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
5127 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
5128 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
5129 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08)
5130{
5131 typedef bslalg::HashTableImpUtil ImpUtil;
5132
5133
5134 if (d_size >= d_capacity) {
5135 this->rehashForNumBuckets(numBuckets() * 2);
5136 }
5137
5138
5139 bslalg::BidirectionalLink *newNode =
5140 d_parameters.nodeFactory().emplaceIntoNewNode(
5141 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
5142 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
5143 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
5144 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
5145 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
5146 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
5147 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
5148 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08));
5149
5150
5151 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5152 nodeProctor(&d_parameters.nodeFactory(), newNode);
5153
5154
5155 size_t hashCode = this->d_parameters.hashCodeForKey(
5156 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5157 bslalg::BidirectionalLink *position = this->find(
5158 ImpUtil::extractKey<KEY_CONFIG>(newNode),
5159 hashCode);
5160
5161 if (!position) {
5162 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5163 }
5164 else {
5165 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, position);
5166 }
5167 nodeProctor.release();
5168
5169 ++d_size;
5170
5171 return newNode;
5172}
5173#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 8
5174
5175#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 9
5176template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5177template <class ARGS_01,
5178 class ARGS_02,
5179 class ARGS_03,
5180 class ARGS_04,
5181 class ARGS_05,
5182 class ARGS_06,
5183 class ARGS_07,
5184 class ARGS_08,
5185 class ARGS_09>
5187HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplace(
5188 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
5189 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
5190 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
5191 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
5192 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
5193 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
5194 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
5195 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
5196 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09)
5197{
5198 typedef bslalg::HashTableImpUtil ImpUtil;
5199
5200
5201 if (d_size >= d_capacity) {
5202 this->rehashForNumBuckets(numBuckets() * 2);
5203 }
5204
5205
5206 bslalg::BidirectionalLink *newNode =
5207 d_parameters.nodeFactory().emplaceIntoNewNode(
5208 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
5209 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
5210 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
5211 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
5212 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
5213 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
5214 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
5215 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
5216 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09));
5217
5218
5219 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5220 nodeProctor(&d_parameters.nodeFactory(), newNode);
5221
5222
5223 size_t hashCode = this->d_parameters.hashCodeForKey(
5224 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5225 bslalg::BidirectionalLink *position = this->find(
5226 ImpUtil::extractKey<KEY_CONFIG>(newNode),
5227 hashCode);
5228
5229 if (!position) {
5230 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5231 }
5232 else {
5233 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, position);
5234 }
5235 nodeProctor.release();
5236
5237 ++d_size;
5238
5239 return newNode;
5240}
5241#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 9
5242
5243#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 10
5244template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5245template <class ARGS_01,
5246 class ARGS_02,
5247 class ARGS_03,
5248 class ARGS_04,
5249 class ARGS_05,
5250 class ARGS_06,
5251 class ARGS_07,
5252 class ARGS_08,
5253 class ARGS_09,
5254 class ARGS_10>
5256HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplace(
5257 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
5258 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
5259 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
5260 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
5261 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
5262 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
5263 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
5264 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
5265 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
5266 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10)
5267{
5268 typedef bslalg::HashTableImpUtil ImpUtil;
5269
5270
5271 if (d_size >= d_capacity) {
5272 this->rehashForNumBuckets(numBuckets() * 2);
5273 }
5274
5275
5276 bslalg::BidirectionalLink *newNode =
5277 d_parameters.nodeFactory().emplaceIntoNewNode(
5278 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
5279 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
5280 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
5281 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
5282 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
5283 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
5284 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
5285 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
5286 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09),
5287 BSLS_COMPILERFEATURES_FORWARD(ARGS_10, arguments_10));
5288
5289
5290 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5291 nodeProctor(&d_parameters.nodeFactory(), newNode);
5292
5293
5294 size_t hashCode = this->d_parameters.hashCodeForKey(
5295 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5296 bslalg::BidirectionalLink *position = this->find(
5297 ImpUtil::extractKey<KEY_CONFIG>(newNode),
5298 hashCode);
5299
5300 if (!position) {
5301 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5302 }
5303 else {
5304 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, position);
5305 }
5306 nodeProctor.release();
5307
5308 ++d_size;
5309
5310 return newNode;
5311}
5312#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 10
5313
5314
5315#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 0
5316template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5318HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceWithHint(
5320{
5321 typedef bslalg::HashTableImpUtil ImpUtil;
5322
5323
5324 if (d_size >= d_capacity) {
5325 this->rehashForNumBuckets(numBuckets() * 2);
5326 }
5327
5328
5329 bslalg::BidirectionalLink *newNode =
5330 d_parameters.nodeFactory().emplaceIntoNewNode(
5331 );
5332
5333
5334 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5335 nodeProctor(&d_parameters.nodeFactory(), newNode);
5336
5337
5338 size_t hashCode = this->d_parameters.hashCodeForKey(
5339 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5340 if (!hint
5341 || !d_parameters.comparator()(ImpUtil::extractKey<KEY_CONFIG>(newNode),
5342 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
5343 hint = this->find(ImpUtil::extractKey<KEY_CONFIG>(newNode), hashCode);
5344 }
5345
5346 if (!hint) {
5347 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5348 }
5349 else {
5350 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, hint);
5351 }
5352 nodeProctor.release();
5353
5354 ++d_size;
5355
5356 return newNode;
5357}
5358#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 0
5359
5360#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 1
5361template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5362template <class ARGS_01>
5364HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceWithHint(
5366 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01)
5367{
5368 typedef bslalg::HashTableImpUtil ImpUtil;
5369
5370
5371 if (d_size >= d_capacity) {
5372 this->rehashForNumBuckets(numBuckets() * 2);
5373 }
5374
5375
5376 bslalg::BidirectionalLink *newNode =
5377 d_parameters.nodeFactory().emplaceIntoNewNode(
5378 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01));
5379
5380
5381 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5382 nodeProctor(&d_parameters.nodeFactory(), newNode);
5383
5384
5385 size_t hashCode = this->d_parameters.hashCodeForKey(
5386 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5387 if (!hint
5388 || !d_parameters.comparator()(ImpUtil::extractKey<KEY_CONFIG>(newNode),
5389 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
5390 hint = this->find(ImpUtil::extractKey<KEY_CONFIG>(newNode), hashCode);
5391 }
5392
5393 if (!hint) {
5394 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5395 }
5396 else {
5397 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, hint);
5398 }
5399 nodeProctor.release();
5400
5401 ++d_size;
5402
5403 return newNode;
5404}
5405#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 1
5406
5407#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 2
5408template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5409template <class ARGS_01,
5410 class ARGS_02>
5412HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceWithHint(
5414 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
5415 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02)
5416{
5417 typedef bslalg::HashTableImpUtil ImpUtil;
5418
5419
5420 if (d_size >= d_capacity) {
5421 this->rehashForNumBuckets(numBuckets() * 2);
5422 }
5423
5424
5425 bslalg::BidirectionalLink *newNode =
5426 d_parameters.nodeFactory().emplaceIntoNewNode(
5427 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
5428 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02));
5429
5430
5431 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5432 nodeProctor(&d_parameters.nodeFactory(), newNode);
5433
5434
5435 size_t hashCode = this->d_parameters.hashCodeForKey(
5436 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5437 if (!hint
5438 || !d_parameters.comparator()(ImpUtil::extractKey<KEY_CONFIG>(newNode),
5439 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
5440 hint = this->find(ImpUtil::extractKey<KEY_CONFIG>(newNode), hashCode);
5441 }
5442
5443 if (!hint) {
5444 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5445 }
5446 else {
5447 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, hint);
5448 }
5449 nodeProctor.release();
5450
5451 ++d_size;
5452
5453 return newNode;
5454}
5455#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 2
5456
5457#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 3
5458template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5459template <class ARGS_01,
5460 class ARGS_02,
5461 class ARGS_03>
5463HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceWithHint(
5465 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
5466 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
5467 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03)
5468{
5469 typedef bslalg::HashTableImpUtil ImpUtil;
5470
5471
5472 if (d_size >= d_capacity) {
5473 this->rehashForNumBuckets(numBuckets() * 2);
5474 }
5475
5476
5477 bslalg::BidirectionalLink *newNode =
5478 d_parameters.nodeFactory().emplaceIntoNewNode(
5479 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
5480 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
5481 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03));
5482
5483
5484 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5485 nodeProctor(&d_parameters.nodeFactory(), newNode);
5486
5487
5488 size_t hashCode = this->d_parameters.hashCodeForKey(
5489 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5490 if (!hint
5491 || !d_parameters.comparator()(ImpUtil::extractKey<KEY_CONFIG>(newNode),
5492 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
5493 hint = this->find(ImpUtil::extractKey<KEY_CONFIG>(newNode), hashCode);
5494 }
5495
5496 if (!hint) {
5497 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5498 }
5499 else {
5500 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, hint);
5501 }
5502 nodeProctor.release();
5503
5504 ++d_size;
5505
5506 return newNode;
5507}
5508#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 3
5509
5510#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 4
5511template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5512template <class ARGS_01,
5513 class ARGS_02,
5514 class ARGS_03,
5515 class ARGS_04>
5517HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceWithHint(
5519 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
5520 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
5521 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
5522 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04)
5523{
5524 typedef bslalg::HashTableImpUtil ImpUtil;
5525
5526
5527 if (d_size >= d_capacity) {
5528 this->rehashForNumBuckets(numBuckets() * 2);
5529 }
5530
5531
5532 bslalg::BidirectionalLink *newNode =
5533 d_parameters.nodeFactory().emplaceIntoNewNode(
5534 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
5535 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
5536 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
5537 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04));
5538
5539
5540 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5541 nodeProctor(&d_parameters.nodeFactory(), newNode);
5542
5543
5544 size_t hashCode = this->d_parameters.hashCodeForKey(
5545 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5546 if (!hint
5547 || !d_parameters.comparator()(ImpUtil::extractKey<KEY_CONFIG>(newNode),
5548 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
5549 hint = this->find(ImpUtil::extractKey<KEY_CONFIG>(newNode), hashCode);
5550 }
5551
5552 if (!hint) {
5553 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5554 }
5555 else {
5556 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, hint);
5557 }
5558 nodeProctor.release();
5559
5560 ++d_size;
5561
5562 return newNode;
5563}
5564#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 4
5565
5566#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 5
5567template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5568template <class ARGS_01,
5569 class ARGS_02,
5570 class ARGS_03,
5571 class ARGS_04,
5572 class ARGS_05>
5574HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceWithHint(
5576 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
5577 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
5578 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
5579 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
5580 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05)
5581{
5582 typedef bslalg::HashTableImpUtil ImpUtil;
5583
5584
5585 if (d_size >= d_capacity) {
5586 this->rehashForNumBuckets(numBuckets() * 2);
5587 }
5588
5589
5590 bslalg::BidirectionalLink *newNode =
5591 d_parameters.nodeFactory().emplaceIntoNewNode(
5592 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
5593 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
5594 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
5595 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
5596 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05));
5597
5598
5599 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5600 nodeProctor(&d_parameters.nodeFactory(), newNode);
5601
5602
5603 size_t hashCode = this->d_parameters.hashCodeForKey(
5604 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5605 if (!hint
5606 || !d_parameters.comparator()(ImpUtil::extractKey<KEY_CONFIG>(newNode),
5607 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
5608 hint = this->find(ImpUtil::extractKey<KEY_CONFIG>(newNode), hashCode);
5609 }
5610
5611 if (!hint) {
5612 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5613 }
5614 else {
5615 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, hint);
5616 }
5617 nodeProctor.release();
5618
5619 ++d_size;
5620
5621 return newNode;
5622}
5623#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 5
5624
5625#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 6
5626template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5627template <class ARGS_01,
5628 class ARGS_02,
5629 class ARGS_03,
5630 class ARGS_04,
5631 class ARGS_05,
5632 class ARGS_06>
5634HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceWithHint(
5636 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
5637 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
5638 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
5639 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
5640 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
5641 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06)
5642{
5643 typedef bslalg::HashTableImpUtil ImpUtil;
5644
5645
5646 if (d_size >= d_capacity) {
5647 this->rehashForNumBuckets(numBuckets() * 2);
5648 }
5649
5650
5651 bslalg::BidirectionalLink *newNode =
5652 d_parameters.nodeFactory().emplaceIntoNewNode(
5653 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
5654 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
5655 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
5656 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
5657 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
5658 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06));
5659
5660
5661 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5662 nodeProctor(&d_parameters.nodeFactory(), newNode);
5663
5664
5665 size_t hashCode = this->d_parameters.hashCodeForKey(
5666 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5667 if (!hint
5668 || !d_parameters.comparator()(ImpUtil::extractKey<KEY_CONFIG>(newNode),
5669 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
5670 hint = this->find(ImpUtil::extractKey<KEY_CONFIG>(newNode), hashCode);
5671 }
5672
5673 if (!hint) {
5674 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5675 }
5676 else {
5677 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, hint);
5678 }
5679 nodeProctor.release();
5680
5681 ++d_size;
5682
5683 return newNode;
5684}
5685#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 6
5686
5687#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 7
5688template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5689template <class ARGS_01,
5690 class ARGS_02,
5691 class ARGS_03,
5692 class ARGS_04,
5693 class ARGS_05,
5694 class ARGS_06,
5695 class ARGS_07>
5697HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceWithHint(
5699 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
5700 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
5701 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
5702 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
5703 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
5704 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
5705 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07)
5706{
5707 typedef bslalg::HashTableImpUtil ImpUtil;
5708
5709
5710 if (d_size >= d_capacity) {
5711 this->rehashForNumBuckets(numBuckets() * 2);
5712 }
5713
5714
5715 bslalg::BidirectionalLink *newNode =
5716 d_parameters.nodeFactory().emplaceIntoNewNode(
5717 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
5718 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
5719 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
5720 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
5721 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
5722 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
5723 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07));
5724
5725
5726 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5727 nodeProctor(&d_parameters.nodeFactory(), newNode);
5728
5729
5730 size_t hashCode = this->d_parameters.hashCodeForKey(
5731 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5732 if (!hint
5733 || !d_parameters.comparator()(ImpUtil::extractKey<KEY_CONFIG>(newNode),
5734 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
5735 hint = this->find(ImpUtil::extractKey<KEY_CONFIG>(newNode), hashCode);
5736 }
5737
5738 if (!hint) {
5739 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5740 }
5741 else {
5742 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, hint);
5743 }
5744 nodeProctor.release();
5745
5746 ++d_size;
5747
5748 return newNode;
5749}
5750#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 7
5751
5752#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 8
5753template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5754template <class ARGS_01,
5755 class ARGS_02,
5756 class ARGS_03,
5757 class ARGS_04,
5758 class ARGS_05,
5759 class ARGS_06,
5760 class ARGS_07,
5761 class ARGS_08>
5763HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceWithHint(
5765 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
5766 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
5767 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
5768 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
5769 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
5770 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
5771 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
5772 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08)
5773{
5774 typedef bslalg::HashTableImpUtil ImpUtil;
5775
5776
5777 if (d_size >= d_capacity) {
5778 this->rehashForNumBuckets(numBuckets() * 2);
5779 }
5780
5781
5782 bslalg::BidirectionalLink *newNode =
5783 d_parameters.nodeFactory().emplaceIntoNewNode(
5784 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
5785 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
5786 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
5787 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
5788 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
5789 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
5790 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
5791 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08));
5792
5793
5794 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5795 nodeProctor(&d_parameters.nodeFactory(), newNode);
5796
5797
5798 size_t hashCode = this->d_parameters.hashCodeForKey(
5799 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5800 if (!hint
5801 || !d_parameters.comparator()(ImpUtil::extractKey<KEY_CONFIG>(newNode),
5802 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
5803 hint = this->find(ImpUtil::extractKey<KEY_CONFIG>(newNode), hashCode);
5804 }
5805
5806 if (!hint) {
5807 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5808 }
5809 else {
5810 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, hint);
5811 }
5812 nodeProctor.release();
5813
5814 ++d_size;
5815
5816 return newNode;
5817}
5818#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 8
5819
5820#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 9
5821template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5822template <class ARGS_01,
5823 class ARGS_02,
5824 class ARGS_03,
5825 class ARGS_04,
5826 class ARGS_05,
5827 class ARGS_06,
5828 class ARGS_07,
5829 class ARGS_08,
5830 class ARGS_09>
5832HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceWithHint(
5834 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
5835 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
5836 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
5837 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
5838 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
5839 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
5840 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
5841 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
5842 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09)
5843{
5844 typedef bslalg::HashTableImpUtil ImpUtil;
5845
5846
5847 if (d_size >= d_capacity) {
5848 this->rehashForNumBuckets(numBuckets() * 2);
5849 }
5850
5851
5852 bslalg::BidirectionalLink *newNode =
5853 d_parameters.nodeFactory().emplaceIntoNewNode(
5854 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
5855 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
5856 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
5857 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
5858 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
5859 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
5860 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
5861 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
5862 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09));
5863
5864
5865 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5866 nodeProctor(&d_parameters.nodeFactory(), newNode);
5867
5868
5869 size_t hashCode = this->d_parameters.hashCodeForKey(
5870 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5871 if (!hint
5872 || !d_parameters.comparator()(ImpUtil::extractKey<KEY_CONFIG>(newNode),
5873 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
5874 hint = this->find(ImpUtil::extractKey<KEY_CONFIG>(newNode), hashCode);
5875 }
5876
5877 if (!hint) {
5878 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5879 }
5880 else {
5881 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, hint);
5882 }
5883 nodeProctor.release();
5884
5885 ++d_size;
5886
5887 return newNode;
5888}
5889#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 9
5890
5891#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 10
5892template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5893template <class ARGS_01,
5894 class ARGS_02,
5895 class ARGS_03,
5896 class ARGS_04,
5897 class ARGS_05,
5898 class ARGS_06,
5899 class ARGS_07,
5900 class ARGS_08,
5901 class ARGS_09,
5902 class ARGS_10>
5904HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceWithHint(
5906 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
5907 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
5908 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
5909 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
5910 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
5911 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
5912 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
5913 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
5914 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
5915 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10)
5916{
5917 typedef bslalg::HashTableImpUtil ImpUtil;
5918
5919
5920 if (d_size >= d_capacity) {
5921 this->rehashForNumBuckets(numBuckets() * 2);
5922 }
5923
5924
5925 bslalg::BidirectionalLink *newNode =
5926 d_parameters.nodeFactory().emplaceIntoNewNode(
5927 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
5928 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
5929 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
5930 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
5931 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
5932 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
5933 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
5934 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
5935 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09),
5936 BSLS_COMPILERFEATURES_FORWARD(ARGS_10, arguments_10));
5937
5938
5939 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5940 nodeProctor(&d_parameters.nodeFactory(), newNode);
5941
5942
5943 size_t hashCode = this->d_parameters.hashCodeForKey(
5944 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5945 if (!hint
5946 || !d_parameters.comparator()(ImpUtil::extractKey<KEY_CONFIG>(newNode),
5947 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
5948 hint = this->find(ImpUtil::extractKey<KEY_CONFIG>(newNode), hashCode);
5949 }
5950
5951 if (!hint) {
5952 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
5953 }
5954 else {
5955 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, hint);
5956 }
5957 nodeProctor.release();
5958
5959 ++d_size;
5960
5961 return newNode;
5962}
5963#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 10
5964
5965
5966#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 0
5967template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
5969HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceIfMissing(
5970 bool *isInsertedFlag)
5971{
5972 BSLS_ASSERT(isInsertedFlag);
5973
5974 typedef bslalg::HashTableImpUtil ImpUtil;
5975
5976
5977 if (d_size >= d_capacity) {
5978 this->rehashForNumBuckets(numBuckets() * 2);
5979 }
5980
5981
5982 bslalg::BidirectionalLink *newNode =
5983 d_parameters.nodeFactory().emplaceIntoNewNode(
5984 );
5985
5986
5987 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
5988 nodeProctor(&d_parameters.nodeFactory(), newNode);
5989
5990
5991 size_t hashCode = this->d_parameters.hashCodeForKey(
5992 ImpUtil::extractKey<KEY_CONFIG>(newNode));
5993 bslalg::BidirectionalLink *position = this->find(
5994 ImpUtil::extractKey<KEY_CONFIG>(newNode),
5995 hashCode);
5996
5997 *isInsertedFlag = (!position);
5998
5999 if(!position) {
6000 if (d_size >= d_capacity) {
6001 this->rehashForNumBuckets(numBuckets() * 2);
6002 }
6003
6004 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
6005 nodeProctor.release();
6006
6007 ++d_size;
6008 position = newNode;
6009 }
6010
6011 return position;
6012}
6013#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 0
6014
6015#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 1
6016template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6017template <class ARGS_01>
6019HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceIfMissing(
6020 bool *isInsertedFlag,
6021 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01)
6022{
6023 BSLS_ASSERT(isInsertedFlag);
6024
6025 typedef bslalg::HashTableImpUtil ImpUtil;
6026
6027
6028 if (d_size >= d_capacity) {
6029 this->rehashForNumBuckets(numBuckets() * 2);
6030 }
6031
6032
6033 bslalg::BidirectionalLink *newNode =
6034 d_parameters.nodeFactory().emplaceIntoNewNode(
6035 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01));
6036
6037
6038 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
6039 nodeProctor(&d_parameters.nodeFactory(), newNode);
6040
6041
6042 size_t hashCode = this->d_parameters.hashCodeForKey(
6043 ImpUtil::extractKey<KEY_CONFIG>(newNode));
6044 bslalg::BidirectionalLink *position = this->find(
6045 ImpUtil::extractKey<KEY_CONFIG>(newNode),
6046 hashCode);
6047
6048 *isInsertedFlag = (!position);
6049
6050 if(!position) {
6051 if (d_size >= d_capacity) {
6052 this->rehashForNumBuckets(numBuckets() * 2);
6053 }
6054
6055 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
6056 nodeProctor.release();
6057
6058 ++d_size;
6059 position = newNode;
6060 }
6061
6062 return position;
6063}
6064#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 1
6065
6066#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 2
6067template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6068template <class ARGS_01,
6069 class ARGS_02>
6071HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceIfMissing(
6072 bool *isInsertedFlag,
6073 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
6074 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02)
6075{
6076 BSLS_ASSERT(isInsertedFlag);
6077
6078 typedef bslalg::HashTableImpUtil ImpUtil;
6079
6080
6081 if (d_size >= d_capacity) {
6082 this->rehashForNumBuckets(numBuckets() * 2);
6083 }
6084
6085
6086 bslalg::BidirectionalLink *newNode =
6087 d_parameters.nodeFactory().emplaceIntoNewNode(
6088 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
6089 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02));
6090
6091
6092 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
6093 nodeProctor(&d_parameters.nodeFactory(), newNode);
6094
6095
6096 size_t hashCode = this->d_parameters.hashCodeForKey(
6097 ImpUtil::extractKey<KEY_CONFIG>(newNode));
6098 bslalg::BidirectionalLink *position = this->find(
6099 ImpUtil::extractKey<KEY_CONFIG>(newNode),
6100 hashCode);
6101
6102 *isInsertedFlag = (!position);
6103
6104 if(!position) {
6105 if (d_size >= d_capacity) {
6106 this->rehashForNumBuckets(numBuckets() * 2);
6107 }
6108
6109 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
6110 nodeProctor.release();
6111
6112 ++d_size;
6113 position = newNode;
6114 }
6115
6116 return position;
6117}
6118#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 2
6119
6120#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 3
6121template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6122template <class ARGS_01,
6123 class ARGS_02,
6124 class ARGS_03>
6126HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceIfMissing(
6127 bool *isInsertedFlag,
6128 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
6129 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
6130 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03)
6131{
6132 BSLS_ASSERT(isInsertedFlag);
6133
6134 typedef bslalg::HashTableImpUtil ImpUtil;
6135
6136
6137 if (d_size >= d_capacity) {
6138 this->rehashForNumBuckets(numBuckets() * 2);
6139 }
6140
6141
6142 bslalg::BidirectionalLink *newNode =
6143 d_parameters.nodeFactory().emplaceIntoNewNode(
6144 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
6145 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
6146 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03));
6147
6148
6149 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
6150 nodeProctor(&d_parameters.nodeFactory(), newNode);
6151
6152
6153 size_t hashCode = this->d_parameters.hashCodeForKey(
6154 ImpUtil::extractKey<KEY_CONFIG>(newNode));
6155 bslalg::BidirectionalLink *position = this->find(
6156 ImpUtil::extractKey<KEY_CONFIG>(newNode),
6157 hashCode);
6158
6159 *isInsertedFlag = (!position);
6160
6161 if(!position) {
6162 if (d_size >= d_capacity) {
6163 this->rehashForNumBuckets(numBuckets() * 2);
6164 }
6165
6166 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
6167 nodeProctor.release();
6168
6169 ++d_size;
6170 position = newNode;
6171 }
6172
6173 return position;
6174}
6175#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 3
6176
6177#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 4
6178template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6179template <class ARGS_01,
6180 class ARGS_02,
6181 class ARGS_03,
6182 class ARGS_04>
6184HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceIfMissing(
6185 bool *isInsertedFlag,
6186 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
6187 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
6188 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
6189 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04)
6190{
6191 BSLS_ASSERT(isInsertedFlag);
6192
6193 typedef bslalg::HashTableImpUtil ImpUtil;
6194
6195
6196 if (d_size >= d_capacity) {
6197 this->rehashForNumBuckets(numBuckets() * 2);
6198 }
6199
6200
6201 bslalg::BidirectionalLink *newNode =
6202 d_parameters.nodeFactory().emplaceIntoNewNode(
6203 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
6204 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
6205 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
6206 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04));
6207
6208
6209 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
6210 nodeProctor(&d_parameters.nodeFactory(), newNode);
6211
6212
6213 size_t hashCode = this->d_parameters.hashCodeForKey(
6214 ImpUtil::extractKey<KEY_CONFIG>(newNode));
6215 bslalg::BidirectionalLink *position = this->find(
6216 ImpUtil::extractKey<KEY_CONFIG>(newNode),
6217 hashCode);
6218
6219 *isInsertedFlag = (!position);
6220
6221 if(!position) {
6222 if (d_size >= d_capacity) {
6223 this->rehashForNumBuckets(numBuckets() * 2);
6224 }
6225
6226 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
6227 nodeProctor.release();
6228
6229 ++d_size;
6230 position = newNode;
6231 }
6232
6233 return position;
6234}
6235#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 4
6236
6237#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 5
6238template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6239template <class ARGS_01,
6240 class ARGS_02,
6241 class ARGS_03,
6242 class ARGS_04,
6243 class ARGS_05>
6245HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceIfMissing(
6246 bool *isInsertedFlag,
6247 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
6248 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
6249 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
6250 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
6251 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05)
6252{
6253 BSLS_ASSERT(isInsertedFlag);
6254
6255 typedef bslalg::HashTableImpUtil ImpUtil;
6256
6257
6258 if (d_size >= d_capacity) {
6259 this->rehashForNumBuckets(numBuckets() * 2);
6260 }
6261
6262
6263 bslalg::BidirectionalLink *newNode =
6264 d_parameters.nodeFactory().emplaceIntoNewNode(
6265 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
6266 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
6267 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
6268 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
6269 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05));
6270
6271
6272 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
6273 nodeProctor(&d_parameters.nodeFactory(), newNode);
6274
6275
6276 size_t hashCode = this->d_parameters.hashCodeForKey(
6277 ImpUtil::extractKey<KEY_CONFIG>(newNode));
6278 bslalg::BidirectionalLink *position = this->find(
6279 ImpUtil::extractKey<KEY_CONFIG>(newNode),
6280 hashCode);
6281
6282 *isInsertedFlag = (!position);
6283
6284 if(!position) {
6285 if (d_size >= d_capacity) {
6286 this->rehashForNumBuckets(numBuckets() * 2);
6287 }
6288
6289 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
6290 nodeProctor.release();
6291
6292 ++d_size;
6293 position = newNode;
6294 }
6295
6296 return position;
6297}
6298#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 5
6299
6300#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 6
6301template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6302template <class ARGS_01,
6303 class ARGS_02,
6304 class ARGS_03,
6305 class ARGS_04,
6306 class ARGS_05,
6307 class ARGS_06>
6309HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceIfMissing(
6310 bool *isInsertedFlag,
6311 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
6312 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
6313 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
6314 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
6315 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
6316 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06)
6317{
6318 BSLS_ASSERT(isInsertedFlag);
6319
6320 typedef bslalg::HashTableImpUtil ImpUtil;
6321
6322
6323 if (d_size >= d_capacity) {
6324 this->rehashForNumBuckets(numBuckets() * 2);
6325 }
6326
6327
6328 bslalg::BidirectionalLink *newNode =
6329 d_parameters.nodeFactory().emplaceIntoNewNode(
6330 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
6331 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
6332 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
6333 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
6334 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
6335 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06));
6336
6337
6338 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
6339 nodeProctor(&d_parameters.nodeFactory(), newNode);
6340
6341
6342 size_t hashCode = this->d_parameters.hashCodeForKey(
6343 ImpUtil::extractKey<KEY_CONFIG>(newNode));
6344 bslalg::BidirectionalLink *position = this->find(
6345 ImpUtil::extractKey<KEY_CONFIG>(newNode),
6346 hashCode);
6347
6348 *isInsertedFlag = (!position);
6349
6350 if(!position) {
6351 if (d_size >= d_capacity) {
6352 this->rehashForNumBuckets(numBuckets() * 2);
6353 }
6354
6355 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
6356 nodeProctor.release();
6357
6358 ++d_size;
6359 position = newNode;
6360 }
6361
6362 return position;
6363}
6364#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 6
6365
6366#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 7
6367template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6368template <class ARGS_01,
6369 class ARGS_02,
6370 class ARGS_03,
6371 class ARGS_04,
6372 class ARGS_05,
6373 class ARGS_06,
6374 class ARGS_07>
6376HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceIfMissing(
6377 bool *isInsertedFlag,
6378 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
6379 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
6380 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
6381 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
6382 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
6383 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
6384 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07)
6385{
6386 BSLS_ASSERT(isInsertedFlag);
6387
6388 typedef bslalg::HashTableImpUtil ImpUtil;
6389
6390
6391 if (d_size >= d_capacity) {
6392 this->rehashForNumBuckets(numBuckets() * 2);
6393 }
6394
6395
6396 bslalg::BidirectionalLink *newNode =
6397 d_parameters.nodeFactory().emplaceIntoNewNode(
6398 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
6399 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
6400 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
6401 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
6402 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
6403 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
6404 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07));
6405
6406
6407 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
6408 nodeProctor(&d_parameters.nodeFactory(), newNode);
6409
6410
6411 size_t hashCode = this->d_parameters.hashCodeForKey(
6412 ImpUtil::extractKey<KEY_CONFIG>(newNode));
6413 bslalg::BidirectionalLink *position = this->find(
6414 ImpUtil::extractKey<KEY_CONFIG>(newNode),
6415 hashCode);
6416
6417 *isInsertedFlag = (!position);
6418
6419 if(!position) {
6420 if (d_size >= d_capacity) {
6421 this->rehashForNumBuckets(numBuckets() * 2);
6422 }
6423
6424 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
6425 nodeProctor.release();
6426
6427 ++d_size;
6428 position = newNode;
6429 }
6430
6431 return position;
6432}
6433#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 7
6434
6435#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 8
6436template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6437template <class ARGS_01,
6438 class ARGS_02,
6439 class ARGS_03,
6440 class ARGS_04,
6441 class ARGS_05,
6442 class ARGS_06,
6443 class ARGS_07,
6444 class ARGS_08>
6446HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceIfMissing(
6447 bool *isInsertedFlag,
6448 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
6449 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
6450 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
6451 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
6452 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
6453 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
6454 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
6455 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08)
6456{
6457 BSLS_ASSERT(isInsertedFlag);
6458
6459 typedef bslalg::HashTableImpUtil ImpUtil;
6460
6461
6462 if (d_size >= d_capacity) {
6463 this->rehashForNumBuckets(numBuckets() * 2);
6464 }
6465
6466
6467 bslalg::BidirectionalLink *newNode =
6468 d_parameters.nodeFactory().emplaceIntoNewNode(
6469 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
6470 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
6471 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
6472 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
6473 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
6474 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
6475 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
6476 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08));
6477
6478
6479 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
6480 nodeProctor(&d_parameters.nodeFactory(), newNode);
6481
6482
6483 size_t hashCode = this->d_parameters.hashCodeForKey(
6484 ImpUtil::extractKey<KEY_CONFIG>(newNode));
6485 bslalg::BidirectionalLink *position = this->find(
6486 ImpUtil::extractKey<KEY_CONFIG>(newNode),
6487 hashCode);
6488
6489 *isInsertedFlag = (!position);
6490
6491 if(!position) {
6492 if (d_size >= d_capacity) {
6493 this->rehashForNumBuckets(numBuckets() * 2);
6494 }
6495
6496 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
6497 nodeProctor.release();
6498
6499 ++d_size;
6500 position = newNode;
6501 }
6502
6503 return position;
6504}
6505#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 8
6506
6507#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 9
6508template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6509template <class ARGS_01,
6510 class ARGS_02,
6511 class ARGS_03,
6512 class ARGS_04,
6513 class ARGS_05,
6514 class ARGS_06,
6515 class ARGS_07,
6516 class ARGS_08,
6517 class ARGS_09>
6519HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceIfMissing(
6520 bool *isInsertedFlag,
6521 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
6522 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
6523 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
6524 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
6525 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
6526 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
6527 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
6528 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
6529 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09)
6530{
6531 BSLS_ASSERT(isInsertedFlag);
6532
6533 typedef bslalg::HashTableImpUtil ImpUtil;
6534
6535
6536 if (d_size >= d_capacity) {
6537 this->rehashForNumBuckets(numBuckets() * 2);
6538 }
6539
6540
6541 bslalg::BidirectionalLink *newNode =
6542 d_parameters.nodeFactory().emplaceIntoNewNode(
6543 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
6544 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
6545 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
6546 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
6547 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
6548 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
6549 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
6550 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
6551 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09));
6552
6553
6554 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
6555 nodeProctor(&d_parameters.nodeFactory(), newNode);
6556
6557
6558 size_t hashCode = this->d_parameters.hashCodeForKey(
6559 ImpUtil::extractKey<KEY_CONFIG>(newNode));
6560 bslalg::BidirectionalLink *position = this->find(
6561 ImpUtil::extractKey<KEY_CONFIG>(newNode),
6562 hashCode);
6563
6564 *isInsertedFlag = (!position);
6565
6566 if(!position) {
6567 if (d_size >= d_capacity) {
6568 this->rehashForNumBuckets(numBuckets() * 2);
6569 }
6570
6571 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
6572 nodeProctor.release();
6573
6574 ++d_size;
6575 position = newNode;
6576 }
6577
6578 return position;
6579}
6580#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 9
6581
6582#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 10
6583template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6584template <class ARGS_01,
6585 class ARGS_02,
6586 class ARGS_03,
6587 class ARGS_04,
6588 class ARGS_05,
6589 class ARGS_06,
6590 class ARGS_07,
6591 class ARGS_08,
6592 class ARGS_09,
6593 class ARGS_10>
6595HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceIfMissing(
6596 bool *isInsertedFlag,
6597 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01,
6598 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02,
6599 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03,
6600 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04,
6601 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05,
6602 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06,
6603 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07,
6604 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08,
6605 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09,
6606 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10)
6607{
6608 BSLS_ASSERT(isInsertedFlag);
6609
6610 typedef bslalg::HashTableImpUtil ImpUtil;
6611
6612
6613 if (d_size >= d_capacity) {
6614 this->rehashForNumBuckets(numBuckets() * 2);
6615 }
6616
6617
6618 bslalg::BidirectionalLink *newNode =
6619 d_parameters.nodeFactory().emplaceIntoNewNode(
6620 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, arguments_01),
6621 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, arguments_02),
6622 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, arguments_03),
6623 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, arguments_04),
6624 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, arguments_05),
6625 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, arguments_06),
6626 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, arguments_07),
6627 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, arguments_08),
6628 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, arguments_09),
6629 BSLS_COMPILERFEATURES_FORWARD(ARGS_10, arguments_10));
6630
6631
6632 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
6633 nodeProctor(&d_parameters.nodeFactory(), newNode);
6634
6635
6636 size_t hashCode = this->d_parameters.hashCodeForKey(
6637 ImpUtil::extractKey<KEY_CONFIG>(newNode));
6638 bslalg::BidirectionalLink *position = this->find(
6639 ImpUtil::extractKey<KEY_CONFIG>(newNode),
6640 hashCode);
6641
6642 *isInsertedFlag = (!position);
6643
6644 if(!position) {
6645 if (d_size >= d_capacity) {
6646 this->rehashForNumBuckets(numBuckets() * 2);
6647 }
6648
6649 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
6650 nodeProctor.release();
6651
6652 ++d_size;
6653 position = newNode;
6654 }
6655
6656 return position;
6657}
6658#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_E >= 10
6659
6660#else
6661// The generated code below is a workaround for the absence of perfect
6662// forwarding in some compilers.
6663template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6664template <class... ARGS>
6666HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplace(
6667 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments)
6668{
6669 typedef bslalg::HashTableImpUtil ImpUtil;
6670
6671
6672 if (d_size >= d_capacity) {
6673 this->rehashForNumBuckets(numBuckets() * 2);
6674 }
6675
6676
6677 bslalg::BidirectionalLink *newNode =
6678 d_parameters.nodeFactory().emplaceIntoNewNode(
6679 BSLS_COMPILERFEATURES_FORWARD(ARGS, arguments)...);
6680
6681
6682 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
6683 nodeProctor(&d_parameters.nodeFactory(), newNode);
6684
6685
6686 size_t hashCode = this->d_parameters.hashCodeForKey(
6687 ImpUtil::extractKey<KEY_CONFIG>(newNode));
6688 bslalg::BidirectionalLink *position = this->find(
6689 ImpUtil::extractKey<KEY_CONFIG>(newNode),
6690 hashCode);
6691
6692 if (!position) {
6693 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
6694 }
6695 else {
6696 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, position);
6697 }
6698 nodeProctor.release();
6699
6700 ++d_size;
6701
6702 return newNode;
6703}
6704
6705template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6706template <class... ARGS>
6708HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceWithHint(
6710 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments)
6711{
6712 typedef bslalg::HashTableImpUtil ImpUtil;
6713
6714
6715 if (d_size >= d_capacity) {
6716 this->rehashForNumBuckets(numBuckets() * 2);
6717 }
6718
6719
6720 bslalg::BidirectionalLink *newNode =
6721 d_parameters.nodeFactory().emplaceIntoNewNode(
6722 BSLS_COMPILERFEATURES_FORWARD(ARGS, arguments)...);
6723
6724
6725 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
6726 nodeProctor(&d_parameters.nodeFactory(), newNode);
6727
6728
6729 size_t hashCode = this->d_parameters.hashCodeForKey(
6730 ImpUtil::extractKey<KEY_CONFIG>(newNode));
6731 if (!hint
6732 || !d_parameters.comparator()(ImpUtil::extractKey<KEY_CONFIG>(newNode),
6733 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
6734 hint = this->find(ImpUtil::extractKey<KEY_CONFIG>(newNode), hashCode);
6735 }
6736
6737 if (!hint) {
6738 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
6739 }
6740 else {
6741 ImpUtil::insertAtPosition(&d_anchor, newNode, hashCode, hint);
6742 }
6743 nodeProctor.release();
6744
6745 ++d_size;
6746
6747 return newNode;
6748}
6749
6750template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6751template <class... ARGS>
6753HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::emplaceIfMissing(
6754 bool *isInsertedFlag,
6755 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments)
6756{
6757 BSLS_ASSERT(isInsertedFlag);
6758
6759 typedef bslalg::HashTableImpUtil ImpUtil;
6760
6761
6762 if (d_size >= d_capacity) {
6763 this->rehashForNumBuckets(numBuckets() * 2);
6764 }
6765
6766
6767 bslalg::BidirectionalLink *newNode =
6768 d_parameters.nodeFactory().emplaceIntoNewNode(
6769 BSLS_COMPILERFEATURES_FORWARD(ARGS, arguments)...);
6770
6771
6772 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
6773 nodeProctor(&d_parameters.nodeFactory(), newNode);
6774
6775
6776 size_t hashCode = this->d_parameters.hashCodeForKey(
6777 ImpUtil::extractKey<KEY_CONFIG>(newNode));
6778 bslalg::BidirectionalLink *position = this->find(
6779 ImpUtil::extractKey<KEY_CONFIG>(newNode),
6780 hashCode);
6781
6782 *isInsertedFlag = (!position);
6783
6784 if(!position) {
6785 if (d_size >= d_capacity) {
6786 this->rehashForNumBuckets(numBuckets() * 2);
6787 }
6788
6789 ImpUtil::insertAtFrontOfBucket(&d_anchor, newNode, hashCode);
6790 nodeProctor.release();
6791
6792 ++d_size;
6793 position = newNode;
6794 }
6795
6796 return position;
6797}
6798// }}} END GENERATED CODE
6799#endif
6800
6801template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6803HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::insertIfMissing(
6804 const KeyType& key)
6805{
6806 bool dummy = false;
6807 return tryEmplace(&dummy, (bslalg::BidirectionalLink*)0, key);
6808}
6809
6810template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6812HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::insertIfMissing(
6814{
6815 bool dummy = false;
6816 return tryEmplace(&dummy,
6818 MoveUtil::move(key));
6819}
6820
6821template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6823HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::insertIfMissing(
6824 bool *isInsertedFlag,
6825 const ValueType& value)
6826{
6827 BSLS_ASSERT(isInsertedFlag);
6828
6829 size_t hashCode = this->d_parameters.hashCodeForKey(
6830 KEY_CONFIG::extractKey(value));
6831 bslalg::BidirectionalLink *position = this->find(
6832 KEY_CONFIG::extractKey(value),
6833 hashCode);
6834
6835 *isInsertedFlag = (!position);
6836
6837 if(!position) {
6838 if (d_size >= d_capacity) {
6839 this->rehashForNumBuckets(numBuckets() * 2);
6840 }
6841
6842 position = d_parameters.nodeFactory().emplaceIntoNewNode(value);
6844 position,
6845 hashCode);
6846 ++d_size;
6847 }
6848
6849 return position;
6850}
6851
6852template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6854HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::insertIfMissing(
6855 bool *isInsertedFlag,
6857{
6858 ValueType& lvalue = value;
6859
6860 BSLS_ASSERT(isInsertedFlag);
6861
6862 size_t hashCode = this->d_parameters.hashCodeForKey(
6863 KEY_CONFIG::extractKey(lvalue));
6864 bslalg::BidirectionalLink *position = this->find(
6865 KEY_CONFIG::extractKey(lvalue),
6866 hashCode);
6867
6868 *isInsertedFlag = (!position);
6869
6870 if(!position) {
6871 if (d_size >= d_capacity) {
6872 this->rehashForNumBuckets(numBuckets() * 2);
6873 }
6874
6875 position = d_parameters.nodeFactory().emplaceIntoNewNode(
6876 MoveUtil::move(lvalue));
6878 position,
6879 hashCode);
6880 ++d_size;
6881 }
6882
6883 return position;
6884}
6885
6886template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6887template <class SOURCE_TYPE>
6888inline
6890HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::insertIfMissing(
6891 bool *isInsertedFlag,
6892 BSLS_COMPILERFEATURES_FORWARD_REF(SOURCE_TYPE) value)
6893{
6894 BSLS_ASSERT(isInsertedFlag);
6895
6896 return emplaceIfMissing(isInsertedFlag,
6897 BSLS_COMPILERFEATURES_FORWARD(SOURCE_TYPE, value));
6898
6899}
6900
6901template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6902template <class SOURCE_TYPE>
6903inline
6905HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::insert(
6906 BSLS_COMPILERFEATURES_FORWARD_REF(SOURCE_TYPE) value)
6907{
6908 return emplace(BSLS_COMPILERFEATURES_FORWARD(SOURCE_TYPE, value));
6909}
6910
6911template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6912template <class SOURCE_TYPE>
6913inline
6915HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::insert(
6916 BSLS_COMPILERFEATURES_FORWARD_REF(SOURCE_TYPE) value,
6918{
6919 return emplaceWithHint(hint,
6920 BSLS_COMPILERFEATURES_FORWARD(SOURCE_TYPE, value));
6921}
6922
6923// {{{ BEGIN GENERATED CODE
6924// The generated code below is a workaround for the absence of perfect
6925// forwarding in some compilers.
6926template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6927template <class KEY_ARG, class BDE_OTHER_TYPE>
6929HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::insertOrAssign(
6930 bool *isInsertedFlag,
6933 BSLS_COMPILERFEATURES_FORWARD_REF(BDE_OTHER_TYPE) obj)
6934{
6935 typedef bslalg::HashTableImpUtil ImpUtil;
6936
6937 const KEY_ARG& lvalue = key;
6938 size_t hashCode = this->d_parameters.hashCodeForKey(lvalue);
6939 if (!hint
6940 || !d_parameters.comparator()(lvalue,
6941 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
6942 hint = this->find(lvalue, hashCode);
6943 }
6944
6945 if (hint) {
6946 static_cast<NodeType *>(hint)->value().second =
6947 BSLS_COMPILERFEATURES_FORWARD(BDE_OTHER_TYPE, obj);
6948 *isInsertedFlag = false;
6949 return hint;
6950 }
6951
6952 if (d_size >= d_capacity) {
6953 this->rehashForNumBuckets(numBuckets() * 2);
6954 }
6955
6956 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
6957 BSLS_COMPILERFEATURES_FORWARD(KEY_ARG, key),
6958 BSLS_COMPILERFEATURES_FORWARD(BDE_OTHER_TYPE, obj));
6959
6960 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
6961 nodeProctor(&d_parameters.nodeFactory(), hint);
6962 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
6963 nodeProctor.release();
6964 ++d_size;
6965
6966 *isInsertedFlag = true;
6967 return hint;
6968}
6969// }}} END GENERATED CODE
6970
6971template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6972void
6973HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::rehashForNumBuckets(
6974 SizeType newNumBuckets)
6975{
6976 if (newNumBuckets > this->numBuckets()) {
6977 // Compute a "good" number of buckets, e.g., pick a prime number from a
6978 // sorted array of exponentially increasing primes.
6979
6980 size_t capacity;
6981 SizeType numBuckets = static_cast<SizeType>(
6982 HashTable_ImpDetails::growBucketsForLoadFactor(
6983 &capacity,
6984 d_size + 1u,
6985 static_cast<size_t>(newNumBuckets),
6986 d_maxLoadFactor));
6987
6988 this->rehashIntoExactlyNumBuckets(numBuckets,
6989 static_cast<SizeType>(capacity));
6990 }
6991}
6992
6993template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
6995HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::remove(
6997{
6998 BSLS_ASSERT_SAFE(node);
7000 || d_anchor.listRootAddress() == node);
7001
7002 bslalg::BidirectionalLink *result = node->nextLink();
7003
7005 node,
7006 hashCodeForNode(node));
7007 --d_size;
7008
7009 d_parameters.nodeFactory().deleteNode(static_cast<NodeType *>(node));
7010
7011 return result;
7012}
7013
7014template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
7015void
7016HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::removeAll()
7017{
7018 this->removeAllImp();
7019 if (HashTable_ImpDetails::defaultBucketAddress() !=
7020 d_anchor.bucketArrayAddress()) {
7021 std::memset(d_anchor.bucketArrayAddress(),
7022 0,
7023 sizeof(bslalg::HashTableBucket) *
7024 d_anchor.bucketArraySize());
7025 }
7026
7027 d_anchor.setListRootAddress(0);
7028 d_size = 0;
7029}
7030
7031template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
7032inline
7033void
7034HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::reserveForNumElements(
7035 SizeType numElements)
7036{
7037 if (numElements < 1) { // Return avoids undefined behavior in node factory.
7038 return; // RETURN
7039 }
7040
7041 if (numElements > d_capacity) {
7042 // Compute a "good" number of buckets, e.g., pick a prime number from a
7043 // sorted array of exponentially increasing primes.
7044
7045 size_t capacity;
7046 SizeType numBuckets = static_cast<SizeType>(
7047 HashTable_ImpDetails::growBucketsForLoadFactor(
7048 &capacity,
7049 numElements,
7050 static_cast<size_t>(this->numBuckets()),
7051 d_maxLoadFactor));
7052
7053 this->rehashIntoExactlyNumBuckets(numBuckets,
7054 static_cast<SizeType>(capacity));
7055 }
7056}
7057
7058template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
7059inline
7060void HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::setMaxLoadFactor(
7061 float newMaxLoadFactor)
7062{
7063 BSLS_ASSERT_SAFE(0.0f < newMaxLoadFactor);
7064
7065 size_t capacity;
7066 SizeType numBuckets = static_cast<SizeType>(
7067 HashTable_ImpDetails::growBucketsForLoadFactor(
7068 &capacity,
7069 std::max<SizeType>(d_size, 1u),
7070 static_cast<size_t>(this->numBuckets()),
7071 newMaxLoadFactor));
7072
7073 this->rehashIntoExactlyNumBuckets(numBuckets,
7074 static_cast<SizeType>(capacity));
7075
7076 // Always set this last, as there is potential to throw exceptions above.
7077
7078 d_maxLoadFactor = newMaxLoadFactor;
7079}
7080
7081template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
7082void
7083HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::swap(HashTable& other)
7084{
7085 // This trait should perform 'if' at compile-time.
7086
7087 if (AllocatorTraits::propagate_on_container_swap::value) {
7088 quickSwapExchangeAllocators(&other);
7089 }
7090 else {
7091 // C++11 behavior: undefined for unequal allocators
7092 // BSLS_ASSERT(allocator() == other.allocator());
7093
7094 BSLS_ASSERT(d_parameters.nodeFactory().allocator() ==
7095 other.d_parameters.nodeFactory().allocator());
7096 quickSwapRetainAllocators(&other);
7097 }
7098}
7099
7100#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
7101// {{{ BEGIN GENERATED CODE
7102// Command line: sim_cpp11_features.pl bslstl_hashtable.h
7103#ifndef BSLSTL_HASHTABLE_VARIADIC_LIMIT
7104#define BSLSTL_HASHTABLE_VARIADIC_LIMIT 10
7105#endif
7106#ifndef BSLSTL_HASHTABLE_VARIADIC_LIMIT_G
7107#define BSLSTL_HASHTABLE_VARIADIC_LIMIT_G BSLSTL_HASHTABLE_VARIADIC_LIMIT
7108#endif
7109#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 0
7110template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
7111inline
7113HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
7114 bool *isInsertedFlag,
7116 const KeyType& key)
7117{
7118 typedef bslalg::HashTableImpUtil ImpUtil;
7119
7120 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
7121
7122 if (!hint
7123 || !d_parameters.comparator()(key,
7124 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
7125 hint = this->find(key, hashCode);
7126 }
7127
7128 if (hint) {
7129 *isInsertedFlag = false;
7130 return hint;
7131 }
7132
7133 if (d_size >= d_capacity) {
7134 this->rehashForNumBuckets(numBuckets() * 2);
7135 }
7136
7137#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
7138 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7139 std::piecewise_construct,
7140 std::forward_as_tuple(key),
7141 std::forward_as_tuple());
7142#else
7143 typedef typename ValueType::second_type MappedType;
7144
7145
7146 AllocatorType alloc = this->allocator();
7147
7148 bsls::ObjectBuffer<MappedType> defaultMapped;
7149 AllocatorTraits::construct(alloc, defaultMapped.address());
7150 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
7151
7152 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7153 key,
7154 defaultMapped.object());
7155#endif
7156
7157 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
7158 nodeProctor(&d_parameters.nodeFactory(), hint);
7159 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
7160 nodeProctor.release();
7161 ++d_size;
7162
7163 *isInsertedFlag = true;
7164 return hint;
7165}
7166#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 0
7167
7168#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 1
7169template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
7170template <class ARGS_01>
7171inline
7173HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
7174 bool *isInsertedFlag,
7176 const KeyType& key,
7177 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01)
7178{
7179 typedef bslalg::HashTableImpUtil ImpUtil;
7180
7181 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
7182
7183 if (!hint
7184 || !d_parameters.comparator()(key,
7185 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
7186 hint = this->find(key, hashCode);
7187 }
7188
7189 if (hint) {
7190 *isInsertedFlag = false;
7191 return hint;
7192 }
7193
7194 if (d_size >= d_capacity) {
7195 this->rehashForNumBuckets(numBuckets() * 2);
7196 }
7197
7198#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
7199 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7200 std::piecewise_construct,
7201 std::forward_as_tuple(key),
7202 std::forward_as_tuple(
7203 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01)));
7204#else
7205 typedef typename ValueType::second_type MappedType;
7206
7207
7208 AllocatorType alloc = this->allocator();
7209
7210 bsls::ObjectBuffer<MappedType> defaultMapped;
7211 AllocatorTraits::construct(alloc, defaultMapped.address(),
7213 args_01));
7214 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
7215
7216 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7217 key,
7218 defaultMapped.object());
7219#endif
7220
7221 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
7222 nodeProctor(&d_parameters.nodeFactory(), hint);
7223 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
7224 nodeProctor.release();
7225 ++d_size;
7226
7227 *isInsertedFlag = true;
7228 return hint;
7229}
7230#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 1
7231
7232#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 2
7233template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
7234template <class ARGS_01,
7235 class ARGS_02>
7236inline
7238HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
7239 bool *isInsertedFlag,
7241 const KeyType& key,
7242 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
7243 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02)
7244{
7245 typedef bslalg::HashTableImpUtil ImpUtil;
7246
7247 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
7248
7249 if (!hint
7250 || !d_parameters.comparator()(key,
7251 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
7252 hint = this->find(key, hashCode);
7253 }
7254
7255 if (hint) {
7256 *isInsertedFlag = false;
7257 return hint;
7258 }
7259
7260 if (d_size >= d_capacity) {
7261 this->rehashForNumBuckets(numBuckets() * 2);
7262 }
7263
7264#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
7265 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7266 std::piecewise_construct,
7267 std::forward_as_tuple(key),
7268 std::forward_as_tuple(
7269 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
7270 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02)));
7271#else
7272 typedef typename ValueType::second_type MappedType;
7273
7274
7275 AllocatorType alloc = this->allocator();
7276
7277 bsls::ObjectBuffer<MappedType> defaultMapped;
7278 AllocatorTraits::construct(alloc, defaultMapped.address(),
7280 args_01),
7282 args_02));
7283 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
7284
7285 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7286 key,
7287 defaultMapped.object());
7288#endif
7289
7290 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
7291 nodeProctor(&d_parameters.nodeFactory(), hint);
7292 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
7293 nodeProctor.release();
7294 ++d_size;
7295
7296 *isInsertedFlag = true;
7297 return hint;
7298}
7299#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 2
7300
7301#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 3
7302template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
7303template <class ARGS_01,
7304 class ARGS_02,
7305 class ARGS_03>
7306inline
7308HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
7309 bool *isInsertedFlag,
7311 const KeyType& key,
7312 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
7313 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
7314 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03)
7315{
7316 typedef bslalg::HashTableImpUtil ImpUtil;
7317
7318 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
7319
7320 if (!hint
7321 || !d_parameters.comparator()(key,
7322 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
7323 hint = this->find(key, hashCode);
7324 }
7325
7326 if (hint) {
7327 *isInsertedFlag = false;
7328 return hint;
7329 }
7330
7331 if (d_size >= d_capacity) {
7332 this->rehashForNumBuckets(numBuckets() * 2);
7333 }
7334
7335#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
7336 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7337 std::piecewise_construct,
7338 std::forward_as_tuple(key),
7339 std::forward_as_tuple(
7340 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
7341 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
7342 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03)));
7343#else
7344 typedef typename ValueType::second_type MappedType;
7345
7346
7347 AllocatorType alloc = this->allocator();
7348
7349 bsls::ObjectBuffer<MappedType> defaultMapped;
7350 AllocatorTraits::construct(alloc, defaultMapped.address(),
7352 args_01),
7354 args_02),
7356 args_03));
7357 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
7358
7359 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7360 key,
7361 defaultMapped.object());
7362#endif
7363
7364 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
7365 nodeProctor(&d_parameters.nodeFactory(), hint);
7366 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
7367 nodeProctor.release();
7368 ++d_size;
7369
7370 *isInsertedFlag = true;
7371 return hint;
7372}
7373#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 3
7374
7375#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 4
7376template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
7377template <class ARGS_01,
7378 class ARGS_02,
7379 class ARGS_03,
7380 class ARGS_04>
7381inline
7383HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
7384 bool *isInsertedFlag,
7386 const KeyType& key,
7387 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
7388 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
7389 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
7390 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04)
7391{
7392 typedef bslalg::HashTableImpUtil ImpUtil;
7393
7394 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
7395
7396 if (!hint
7397 || !d_parameters.comparator()(key,
7398 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
7399 hint = this->find(key, hashCode);
7400 }
7401
7402 if (hint) {
7403 *isInsertedFlag = false;
7404 return hint;
7405 }
7406
7407 if (d_size >= d_capacity) {
7408 this->rehashForNumBuckets(numBuckets() * 2);
7409 }
7410
7411#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
7412 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7413 std::piecewise_construct,
7414 std::forward_as_tuple(key),
7415 std::forward_as_tuple(
7416 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
7417 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
7418 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
7419 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04)));
7420#else
7421 typedef typename ValueType::second_type MappedType;
7422
7423
7424 AllocatorType alloc = this->allocator();
7425
7426 bsls::ObjectBuffer<MappedType> defaultMapped;
7427 AllocatorTraits::construct(alloc, defaultMapped.address(),
7429 args_01),
7431 args_02),
7433 args_03),
7435 args_04));
7436 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
7437
7438 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7439 key,
7440 defaultMapped.object());
7441#endif
7442
7443 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
7444 nodeProctor(&d_parameters.nodeFactory(), hint);
7445 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
7446 nodeProctor.release();
7447 ++d_size;
7448
7449 *isInsertedFlag = true;
7450 return hint;
7451}
7452#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 4
7453
7454#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 5
7455template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
7456template <class ARGS_01,
7457 class ARGS_02,
7458 class ARGS_03,
7459 class ARGS_04,
7460 class ARGS_05>
7461inline
7463HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
7464 bool *isInsertedFlag,
7466 const KeyType& key,
7467 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
7468 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
7469 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
7470 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
7471 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05)
7472{
7473 typedef bslalg::HashTableImpUtil ImpUtil;
7474
7475 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
7476
7477 if (!hint
7478 || !d_parameters.comparator()(key,
7479 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
7480 hint = this->find(key, hashCode);
7481 }
7482
7483 if (hint) {
7484 *isInsertedFlag = false;
7485 return hint;
7486 }
7487
7488 if (d_size >= d_capacity) {
7489 this->rehashForNumBuckets(numBuckets() * 2);
7490 }
7491
7492#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
7493 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7494 std::piecewise_construct,
7495 std::forward_as_tuple(key),
7496 std::forward_as_tuple(
7497 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
7498 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
7499 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
7500 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
7501 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05)));
7502#else
7503 typedef typename ValueType::second_type MappedType;
7504
7505
7506 AllocatorType alloc = this->allocator();
7507
7508 bsls::ObjectBuffer<MappedType> defaultMapped;
7509 AllocatorTraits::construct(alloc, defaultMapped.address(),
7511 args_01),
7513 args_02),
7515 args_03),
7517 args_04),
7519 args_05));
7520 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
7521
7522 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7523 key,
7524 defaultMapped.object());
7525#endif
7526
7527 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
7528 nodeProctor(&d_parameters.nodeFactory(), hint);
7529 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
7530 nodeProctor.release();
7531 ++d_size;
7532
7533 *isInsertedFlag = true;
7534 return hint;
7535}
7536#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 5
7537
7538#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 6
7539template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
7540template <class ARGS_01,
7541 class ARGS_02,
7542 class ARGS_03,
7543 class ARGS_04,
7544 class ARGS_05,
7545 class ARGS_06>
7546inline
7548HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
7549 bool *isInsertedFlag,
7551 const KeyType& key,
7552 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
7553 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
7554 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
7555 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
7556 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
7557 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06)
7558{
7559 typedef bslalg::HashTableImpUtil ImpUtil;
7560
7561 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
7562
7563 if (!hint
7564 || !d_parameters.comparator()(key,
7565 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
7566 hint = this->find(key, hashCode);
7567 }
7568
7569 if (hint) {
7570 *isInsertedFlag = false;
7571 return hint;
7572 }
7573
7574 if (d_size >= d_capacity) {
7575 this->rehashForNumBuckets(numBuckets() * 2);
7576 }
7577
7578#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
7579 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7580 std::piecewise_construct,
7581 std::forward_as_tuple(key),
7582 std::forward_as_tuple(
7583 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
7584 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
7585 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
7586 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
7587 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
7588 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06)));
7589#else
7590 typedef typename ValueType::second_type MappedType;
7591
7592
7593 AllocatorType alloc = this->allocator();
7594
7595 bsls::ObjectBuffer<MappedType> defaultMapped;
7596 AllocatorTraits::construct(alloc, defaultMapped.address(),
7598 args_01),
7600 args_02),
7602 args_03),
7604 args_04),
7606 args_05),
7608 args_06));
7609 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
7610
7611 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7612 key,
7613 defaultMapped.object());
7614#endif
7615
7616 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
7617 nodeProctor(&d_parameters.nodeFactory(), hint);
7618 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
7619 nodeProctor.release();
7620 ++d_size;
7621
7622 *isInsertedFlag = true;
7623 return hint;
7624}
7625#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 6
7626
7627#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 7
7628template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
7629template <class ARGS_01,
7630 class ARGS_02,
7631 class ARGS_03,
7632 class ARGS_04,
7633 class ARGS_05,
7634 class ARGS_06,
7635 class ARGS_07>
7636inline
7638HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
7639 bool *isInsertedFlag,
7641 const KeyType& key,
7642 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
7643 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
7644 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
7645 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
7646 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
7647 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
7648 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07)
7649{
7650 typedef bslalg::HashTableImpUtil ImpUtil;
7651
7652 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
7653
7654 if (!hint
7655 || !d_parameters.comparator()(key,
7656 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
7657 hint = this->find(key, hashCode);
7658 }
7659
7660 if (hint) {
7661 *isInsertedFlag = false;
7662 return hint;
7663 }
7664
7665 if (d_size >= d_capacity) {
7666 this->rehashForNumBuckets(numBuckets() * 2);
7667 }
7668
7669#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
7670 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7671 std::piecewise_construct,
7672 std::forward_as_tuple(key),
7673 std::forward_as_tuple(
7674 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
7675 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
7676 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
7677 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
7678 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
7679 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
7680 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07)));
7681#else
7682 typedef typename ValueType::second_type MappedType;
7683
7684
7685 AllocatorType alloc = this->allocator();
7686
7687 bsls::ObjectBuffer<MappedType> defaultMapped;
7688 AllocatorTraits::construct(alloc, defaultMapped.address(),
7690 args_01),
7692 args_02),
7694 args_03),
7696 args_04),
7698 args_05),
7700 args_06),
7702 args_07));
7703 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
7704
7705 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7706 key,
7707 defaultMapped.object());
7708#endif
7709
7710 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
7711 nodeProctor(&d_parameters.nodeFactory(), hint);
7712 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
7713 nodeProctor.release();
7714 ++d_size;
7715
7716 *isInsertedFlag = true;
7717 return hint;
7718}
7719#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 7
7720
7721#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 8
7722template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
7723template <class ARGS_01,
7724 class ARGS_02,
7725 class ARGS_03,
7726 class ARGS_04,
7727 class ARGS_05,
7728 class ARGS_06,
7729 class ARGS_07,
7730 class ARGS_08>
7731inline
7733HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
7734 bool *isInsertedFlag,
7736 const KeyType& key,
7737 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
7738 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
7739 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
7740 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
7741 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
7742 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
7743 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
7744 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08)
7745{
7746 typedef bslalg::HashTableImpUtil ImpUtil;
7747
7748 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
7749
7750 if (!hint
7751 || !d_parameters.comparator()(key,
7752 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
7753 hint = this->find(key, hashCode);
7754 }
7755
7756 if (hint) {
7757 *isInsertedFlag = false;
7758 return hint;
7759 }
7760
7761 if (d_size >= d_capacity) {
7762 this->rehashForNumBuckets(numBuckets() * 2);
7763 }
7764
7765#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
7766 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7767 std::piecewise_construct,
7768 std::forward_as_tuple(key),
7769 std::forward_as_tuple(
7770 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
7771 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
7772 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
7773 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
7774 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
7775 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
7776 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
7777 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08)));
7778#else
7779 typedef typename ValueType::second_type MappedType;
7780
7781
7782 AllocatorType alloc = this->allocator();
7783
7784 bsls::ObjectBuffer<MappedType> defaultMapped;
7785 AllocatorTraits::construct(alloc, defaultMapped.address(),
7787 args_01),
7789 args_02),
7791 args_03),
7793 args_04),
7795 args_05),
7797 args_06),
7799 args_07),
7801 args_08));
7802 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
7803
7804 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7805 key,
7806 defaultMapped.object());
7807#endif
7808
7809 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
7810 nodeProctor(&d_parameters.nodeFactory(), hint);
7811 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
7812 nodeProctor.release();
7813 ++d_size;
7814
7815 *isInsertedFlag = true;
7816 return hint;
7817}
7818#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 8
7819
7820#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 9
7821template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
7822template <class ARGS_01,
7823 class ARGS_02,
7824 class ARGS_03,
7825 class ARGS_04,
7826 class ARGS_05,
7827 class ARGS_06,
7828 class ARGS_07,
7829 class ARGS_08,
7830 class ARGS_09>
7831inline
7833HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
7834 bool *isInsertedFlag,
7836 const KeyType& key,
7837 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
7838 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
7839 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
7840 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
7841 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
7842 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
7843 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
7844 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
7845 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09)
7846{
7847 typedef bslalg::HashTableImpUtil ImpUtil;
7848
7849 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
7850
7851 if (!hint
7852 || !d_parameters.comparator()(key,
7853 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
7854 hint = this->find(key, hashCode);
7855 }
7856
7857 if (hint) {
7858 *isInsertedFlag = false;
7859 return hint;
7860 }
7861
7862 if (d_size >= d_capacity) {
7863 this->rehashForNumBuckets(numBuckets() * 2);
7864 }
7865
7866#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
7867 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7868 std::piecewise_construct,
7869 std::forward_as_tuple(key),
7870 std::forward_as_tuple(
7871 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
7872 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
7873 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
7874 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
7875 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
7876 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
7877 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
7878 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08),
7879 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09)));
7880#else
7881 typedef typename ValueType::second_type MappedType;
7882
7883
7884 AllocatorType alloc = this->allocator();
7885
7886 bsls::ObjectBuffer<MappedType> defaultMapped;
7887 AllocatorTraits::construct(alloc, defaultMapped.address(),
7889 args_01),
7891 args_02),
7893 args_03),
7895 args_04),
7897 args_05),
7899 args_06),
7901 args_07),
7903 args_08),
7905 args_09));
7906 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
7907
7908 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7909 key,
7910 defaultMapped.object());
7911#endif
7912
7913 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
7914 nodeProctor(&d_parameters.nodeFactory(), hint);
7915 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
7916 nodeProctor.release();
7917 ++d_size;
7918
7919 *isInsertedFlag = true;
7920 return hint;
7921}
7922#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 9
7923
7924#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 10
7925template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
7926template <class ARGS_01,
7927 class ARGS_02,
7928 class ARGS_03,
7929 class ARGS_04,
7930 class ARGS_05,
7931 class ARGS_06,
7932 class ARGS_07,
7933 class ARGS_08,
7934 class ARGS_09,
7935 class ARGS_10>
7936inline
7938HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
7939 bool *isInsertedFlag,
7941 const KeyType& key,
7942 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
7943 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
7944 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
7945 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
7946 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
7947 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
7948 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
7949 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
7950 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
7951 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10)
7952{
7953 typedef bslalg::HashTableImpUtil ImpUtil;
7954
7955 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
7956
7957 if (!hint
7958 || !d_parameters.comparator()(key,
7959 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
7960 hint = this->find(key, hashCode);
7961 }
7962
7963 if (hint) {
7964 *isInsertedFlag = false;
7965 return hint;
7966 }
7967
7968 if (d_size >= d_capacity) {
7969 this->rehashForNumBuckets(numBuckets() * 2);
7970 }
7971
7972#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
7973 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
7974 std::piecewise_construct,
7975 std::forward_as_tuple(key),
7976 std::forward_as_tuple(
7977 BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01),
7978 BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02),
7979 BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03),
7980 BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04),
7981 BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05),
7982 BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06),
7983 BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07),
7984 BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08),
7985 BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09),
7986 BSLS_COMPILERFEATURES_FORWARD(ARGS_10, args_10)));
7987#else
7988 typedef typename ValueType::second_type MappedType;
7989
7990
7991 AllocatorType alloc = this->allocator();
7992
7993 bsls::ObjectBuffer<MappedType> defaultMapped;
7994 AllocatorTraits::construct(alloc, defaultMapped.address(),
7996 args_01),
7998 args_02),
8000 args_03),
8002 args_04),
8004 args_05),
8006 args_06),
8008 args_07),
8010 args_08),
8012 args_09),
8014 args_10));
8015 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
8016
8017 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8018 key,
8019 defaultMapped.object());
8020#endif
8021
8022 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
8023 nodeProctor(&d_parameters.nodeFactory(), hint);
8024 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
8025 nodeProctor.release();
8026 ++d_size;
8027
8028 *isInsertedFlag = true;
8029 return hint;
8030}
8031#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 10
8032
8033
8034
8035#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 0
8036template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
8037inline
8039HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
8040 bool *isInsertedFlag,
8043{
8044 typedef bslalg::HashTableImpUtil ImpUtil;
8045
8046 const KeyType& lvalue = key;
8047 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
8048
8049 if (!hint
8050 || !d_parameters.comparator()(lvalue,
8051 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
8052 hint = this->find(lvalue, hashCode);
8053 }
8054
8055 if (hint) {
8056 *isInsertedFlag = false;
8057 return hint;
8058 }
8059
8060 if (d_size >= d_capacity) {
8061 this->rehashForNumBuckets(numBuckets() * 2);
8062 }
8063
8064#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
8065 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8066 std::piecewise_construct,
8067 std::forward_as_tuple(MoveUtil::move(key)),
8068 std::forward_as_tuple(
8069 ));
8070#else
8071 typedef typename ValueType::second_type MappedType;
8072
8073
8074 AllocatorType alloc = this->allocator();
8075
8076 bsls::ObjectBuffer<MappedType> defaultMapped;
8077 AllocatorTraits::construct(alloc, defaultMapped.address());
8078 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
8079
8080 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8081 MoveUtil::move(key),
8082 defaultMapped.object());
8083#endif
8084
8085 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
8086 nodeProctor(&d_parameters.nodeFactory(), hint);
8087 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
8088 nodeProctor.release();
8089 ++d_size;
8090
8091 *isInsertedFlag = true;
8092 return hint;
8093}
8094#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 0
8095
8096#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 1
8097template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
8098template <class ARGS_01>
8099inline
8101HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
8102 bool *isInsertedFlag,
8105 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01)
8106{
8107 typedef bslalg::HashTableImpUtil ImpUtil;
8108
8109 const KeyType& lvalue = key;
8110 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
8111
8112 if (!hint
8113 || !d_parameters.comparator()(lvalue,
8114 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
8115 hint = this->find(lvalue, hashCode);
8116 }
8117
8118 if (hint) {
8119 *isInsertedFlag = false;
8120 return hint;
8121 }
8122
8123 if (d_size >= d_capacity) {
8124 this->rehashForNumBuckets(numBuckets() * 2);
8125 }
8126
8127#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
8128 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8129 std::piecewise_construct,
8130 std::forward_as_tuple(MoveUtil::move(key)),
8131 std::forward_as_tuple(
8133 args_01)));
8134#else
8135 typedef typename ValueType::second_type MappedType;
8136
8137
8138 AllocatorType alloc = this->allocator();
8139
8140 bsls::ObjectBuffer<MappedType> defaultMapped;
8141 AllocatorTraits::construct(alloc, defaultMapped.address(),
8143 args_01));
8144 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
8145
8146 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8147 MoveUtil::move(key),
8148 defaultMapped.object());
8149#endif
8150
8151 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
8152 nodeProctor(&d_parameters.nodeFactory(), hint);
8153 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
8154 nodeProctor.release();
8155 ++d_size;
8156
8157 *isInsertedFlag = true;
8158 return hint;
8159}
8160#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 1
8161
8162#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 2
8163template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
8164template <class ARGS_01,
8165 class ARGS_02>
8166inline
8168HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
8169 bool *isInsertedFlag,
8172 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
8173 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02)
8174{
8175 typedef bslalg::HashTableImpUtil ImpUtil;
8176
8177 const KeyType& lvalue = key;
8178 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
8179
8180 if (!hint
8181 || !d_parameters.comparator()(lvalue,
8182 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
8183 hint = this->find(lvalue, hashCode);
8184 }
8185
8186 if (hint) {
8187 *isInsertedFlag = false;
8188 return hint;
8189 }
8190
8191 if (d_size >= d_capacity) {
8192 this->rehashForNumBuckets(numBuckets() * 2);
8193 }
8194
8195#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
8196 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8197 std::piecewise_construct,
8198 std::forward_as_tuple(MoveUtil::move(key)),
8199 std::forward_as_tuple(
8201 args_01),
8203 args_02)));
8204#else
8205 typedef typename ValueType::second_type MappedType;
8206
8207
8208 AllocatorType alloc = this->allocator();
8209
8210 bsls::ObjectBuffer<MappedType> defaultMapped;
8211 AllocatorTraits::construct(alloc, defaultMapped.address(),
8213 args_01),
8215 args_02));
8216 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
8217
8218 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8219 MoveUtil::move(key),
8220 defaultMapped.object());
8221#endif
8222
8223 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
8224 nodeProctor(&d_parameters.nodeFactory(), hint);
8225 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
8226 nodeProctor.release();
8227 ++d_size;
8228
8229 *isInsertedFlag = true;
8230 return hint;
8231}
8232#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 2
8233
8234#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 3
8235template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
8236template <class ARGS_01,
8237 class ARGS_02,
8238 class ARGS_03>
8239inline
8241HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
8242 bool *isInsertedFlag,
8245 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
8246 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
8247 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03)
8248{
8249 typedef bslalg::HashTableImpUtil ImpUtil;
8250
8251 const KeyType& lvalue = key;
8252 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
8253
8254 if (!hint
8255 || !d_parameters.comparator()(lvalue,
8256 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
8257 hint = this->find(lvalue, hashCode);
8258 }
8259
8260 if (hint) {
8261 *isInsertedFlag = false;
8262 return hint;
8263 }
8264
8265 if (d_size >= d_capacity) {
8266 this->rehashForNumBuckets(numBuckets() * 2);
8267 }
8268
8269#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
8270 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8271 std::piecewise_construct,
8272 std::forward_as_tuple(MoveUtil::move(key)),
8273 std::forward_as_tuple(
8275 args_01),
8277 args_02),
8279 args_03)));
8280#else
8281 typedef typename ValueType::second_type MappedType;
8282
8283
8284 AllocatorType alloc = this->allocator();
8285
8286 bsls::ObjectBuffer<MappedType> defaultMapped;
8287 AllocatorTraits::construct(alloc, defaultMapped.address(),
8289 args_01),
8291 args_02),
8293 args_03));
8294 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
8295
8296 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8297 MoveUtil::move(key),
8298 defaultMapped.object());
8299#endif
8300
8301 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
8302 nodeProctor(&d_parameters.nodeFactory(), hint);
8303 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
8304 nodeProctor.release();
8305 ++d_size;
8306
8307 *isInsertedFlag = true;
8308 return hint;
8309}
8310#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 3
8311
8312#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 4
8313template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
8314template <class ARGS_01,
8315 class ARGS_02,
8316 class ARGS_03,
8317 class ARGS_04>
8318inline
8320HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
8321 bool *isInsertedFlag,
8324 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
8325 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
8326 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
8327 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04)
8328{
8329 typedef bslalg::HashTableImpUtil ImpUtil;
8330
8331 const KeyType& lvalue = key;
8332 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
8333
8334 if (!hint
8335 || !d_parameters.comparator()(lvalue,
8336 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
8337 hint = this->find(lvalue, hashCode);
8338 }
8339
8340 if (hint) {
8341 *isInsertedFlag = false;
8342 return hint;
8343 }
8344
8345 if (d_size >= d_capacity) {
8346 this->rehashForNumBuckets(numBuckets() * 2);
8347 }
8348
8349#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
8350 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8351 std::piecewise_construct,
8352 std::forward_as_tuple(MoveUtil::move(key)),
8353 std::forward_as_tuple(
8355 args_01),
8357 args_02),
8359 args_03),
8361 args_04)));
8362#else
8363 typedef typename ValueType::second_type MappedType;
8364
8365
8366 AllocatorType alloc = this->allocator();
8367
8368 bsls::ObjectBuffer<MappedType> defaultMapped;
8369 AllocatorTraits::construct(alloc, defaultMapped.address(),
8371 args_01),
8373 args_02),
8375 args_03),
8377 args_04));
8378 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
8379
8380 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8381 MoveUtil::move(key),
8382 defaultMapped.object());
8383#endif
8384
8385 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
8386 nodeProctor(&d_parameters.nodeFactory(), hint);
8387 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
8388 nodeProctor.release();
8389 ++d_size;
8390
8391 *isInsertedFlag = true;
8392 return hint;
8393}
8394#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 4
8395
8396#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 5
8397template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
8398template <class ARGS_01,
8399 class ARGS_02,
8400 class ARGS_03,
8401 class ARGS_04,
8402 class ARGS_05>
8403inline
8405HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
8406 bool *isInsertedFlag,
8409 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
8410 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
8411 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
8412 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
8413 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05)
8414{
8415 typedef bslalg::HashTableImpUtil ImpUtil;
8416
8417 const KeyType& lvalue = key;
8418 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
8419
8420 if (!hint
8421 || !d_parameters.comparator()(lvalue,
8422 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
8423 hint = this->find(lvalue, hashCode);
8424 }
8425
8426 if (hint) {
8427 *isInsertedFlag = false;
8428 return hint;
8429 }
8430
8431 if (d_size >= d_capacity) {
8432 this->rehashForNumBuckets(numBuckets() * 2);
8433 }
8434
8435#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
8436 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8437 std::piecewise_construct,
8438 std::forward_as_tuple(MoveUtil::move(key)),
8439 std::forward_as_tuple(
8441 args_01),
8443 args_02),
8445 args_03),
8447 args_04),
8449 args_05)));
8450#else
8451 typedef typename ValueType::second_type MappedType;
8452
8453
8454 AllocatorType alloc = this->allocator();
8455
8456 bsls::ObjectBuffer<MappedType> defaultMapped;
8457 AllocatorTraits::construct(alloc, defaultMapped.address(),
8459 args_01),
8461 args_02),
8463 args_03),
8465 args_04),
8467 args_05));
8468 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
8469
8470 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8471 MoveUtil::move(key),
8472 defaultMapped.object());
8473#endif
8474
8475 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
8476 nodeProctor(&d_parameters.nodeFactory(), hint);
8477 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
8478 nodeProctor.release();
8479 ++d_size;
8480
8481 *isInsertedFlag = true;
8482 return hint;
8483}
8484#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 5
8485
8486#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 6
8487template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
8488template <class ARGS_01,
8489 class ARGS_02,
8490 class ARGS_03,
8491 class ARGS_04,
8492 class ARGS_05,
8493 class ARGS_06>
8494inline
8496HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
8497 bool *isInsertedFlag,
8500 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
8501 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
8502 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
8503 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
8504 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
8505 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06)
8506{
8507 typedef bslalg::HashTableImpUtil ImpUtil;
8508
8509 const KeyType& lvalue = key;
8510 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
8511
8512 if (!hint
8513 || !d_parameters.comparator()(lvalue,
8514 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
8515 hint = this->find(lvalue, hashCode);
8516 }
8517
8518 if (hint) {
8519 *isInsertedFlag = false;
8520 return hint;
8521 }
8522
8523 if (d_size >= d_capacity) {
8524 this->rehashForNumBuckets(numBuckets() * 2);
8525 }
8526
8527#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
8528 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8529 std::piecewise_construct,
8530 std::forward_as_tuple(MoveUtil::move(key)),
8531 std::forward_as_tuple(
8533 args_01),
8535 args_02),
8537 args_03),
8539 args_04),
8541 args_05),
8543 args_06)));
8544#else
8545 typedef typename ValueType::second_type MappedType;
8546
8547
8548 AllocatorType alloc = this->allocator();
8549
8550 bsls::ObjectBuffer<MappedType> defaultMapped;
8551 AllocatorTraits::construct(alloc, defaultMapped.address(),
8553 args_01),
8555 args_02),
8557 args_03),
8559 args_04),
8561 args_05),
8563 args_06));
8564 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
8565
8566 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8567 MoveUtil::move(key),
8568 defaultMapped.object());
8569#endif
8570
8571 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
8572 nodeProctor(&d_parameters.nodeFactory(), hint);
8573 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
8574 nodeProctor.release();
8575 ++d_size;
8576
8577 *isInsertedFlag = true;
8578 return hint;
8579}
8580#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 6
8581
8582#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 7
8583template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
8584template <class ARGS_01,
8585 class ARGS_02,
8586 class ARGS_03,
8587 class ARGS_04,
8588 class ARGS_05,
8589 class ARGS_06,
8590 class ARGS_07>
8591inline
8593HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
8594 bool *isInsertedFlag,
8597 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
8598 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
8599 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
8600 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
8601 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
8602 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
8603 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07)
8604{
8605 typedef bslalg::HashTableImpUtil ImpUtil;
8606
8607 const KeyType& lvalue = key;
8608 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
8609
8610 if (!hint
8611 || !d_parameters.comparator()(lvalue,
8612 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
8613 hint = this->find(lvalue, hashCode);
8614 }
8615
8616 if (hint) {
8617 *isInsertedFlag = false;
8618 return hint;
8619 }
8620
8621 if (d_size >= d_capacity) {
8622 this->rehashForNumBuckets(numBuckets() * 2);
8623 }
8624
8625#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
8626 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8627 std::piecewise_construct,
8628 std::forward_as_tuple(MoveUtil::move(key)),
8629 std::forward_as_tuple(
8631 args_01),
8633 args_02),
8635 args_03),
8637 args_04),
8639 args_05),
8641 args_06),
8643 args_07)));
8644#else
8645 typedef typename ValueType::second_type MappedType;
8646
8647
8648 AllocatorType alloc = this->allocator();
8649
8650 bsls::ObjectBuffer<MappedType> defaultMapped;
8651 AllocatorTraits::construct(alloc, defaultMapped.address(),
8653 args_01),
8655 args_02),
8657 args_03),
8659 args_04),
8661 args_05),
8663 args_06),
8665 args_07));
8666 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
8667
8668 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8669 MoveUtil::move(key),
8670 defaultMapped.object());
8671#endif
8672
8673 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
8674 nodeProctor(&d_parameters.nodeFactory(), hint);
8675 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
8676 nodeProctor.release();
8677 ++d_size;
8678
8679 *isInsertedFlag = true;
8680 return hint;
8681}
8682#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 7
8683
8684#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 8
8685template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
8686template <class ARGS_01,
8687 class ARGS_02,
8688 class ARGS_03,
8689 class ARGS_04,
8690 class ARGS_05,
8691 class ARGS_06,
8692 class ARGS_07,
8693 class ARGS_08>
8694inline
8696HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
8697 bool *isInsertedFlag,
8700 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
8701 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
8702 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
8703 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
8704 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
8705 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
8706 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
8707 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08)
8708{
8709 typedef bslalg::HashTableImpUtil ImpUtil;
8710
8711 const KeyType& lvalue = key;
8712 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
8713
8714 if (!hint
8715 || !d_parameters.comparator()(lvalue,
8716 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
8717 hint = this->find(lvalue, hashCode);
8718 }
8719
8720 if (hint) {
8721 *isInsertedFlag = false;
8722 return hint;
8723 }
8724
8725 if (d_size >= d_capacity) {
8726 this->rehashForNumBuckets(numBuckets() * 2);
8727 }
8728
8729#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
8730 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8731 std::piecewise_construct,
8732 std::forward_as_tuple(MoveUtil::move(key)),
8733 std::forward_as_tuple(
8735 args_01),
8737 args_02),
8739 args_03),
8741 args_04),
8743 args_05),
8745 args_06),
8747 args_07),
8749 args_08)));
8750#else
8751 typedef typename ValueType::second_type MappedType;
8752
8753
8754 AllocatorType alloc = this->allocator();
8755
8756 bsls::ObjectBuffer<MappedType> defaultMapped;
8757 AllocatorTraits::construct(alloc, defaultMapped.address(),
8759 args_01),
8761 args_02),
8763 args_03),
8765 args_04),
8767 args_05),
8769 args_06),
8771 args_07),
8773 args_08));
8774 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
8775
8776 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8777 MoveUtil::move(key),
8778 defaultMapped.object());
8779#endif
8780
8781 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
8782 nodeProctor(&d_parameters.nodeFactory(), hint);
8783 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
8784 nodeProctor.release();
8785 ++d_size;
8786
8787 *isInsertedFlag = true;
8788 return hint;
8789}
8790#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 8
8791
8792#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 9
8793template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
8794template <class ARGS_01,
8795 class ARGS_02,
8796 class ARGS_03,
8797 class ARGS_04,
8798 class ARGS_05,
8799 class ARGS_06,
8800 class ARGS_07,
8801 class ARGS_08,
8802 class ARGS_09>
8803inline
8805HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
8806 bool *isInsertedFlag,
8809 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
8810 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
8811 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
8812 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
8813 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
8814 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
8815 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
8816 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
8817 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09)
8818{
8819 typedef bslalg::HashTableImpUtil ImpUtil;
8820
8821 const KeyType& lvalue = key;
8822 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
8823
8824 if (!hint
8825 || !d_parameters.comparator()(lvalue,
8826 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
8827 hint = this->find(lvalue, hashCode);
8828 }
8829
8830 if (hint) {
8831 *isInsertedFlag = false;
8832 return hint;
8833 }
8834
8835 if (d_size >= d_capacity) {
8836 this->rehashForNumBuckets(numBuckets() * 2);
8837 }
8838
8839#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
8840 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8841 std::piecewise_construct,
8842 std::forward_as_tuple(MoveUtil::move(key)),
8843 std::forward_as_tuple(
8845 args_01),
8847 args_02),
8849 args_03),
8851 args_04),
8853 args_05),
8855 args_06),
8857 args_07),
8859 args_08),
8861 args_09)));
8862#else
8863 typedef typename ValueType::second_type MappedType;
8864
8865
8866 AllocatorType alloc = this->allocator();
8867
8868 bsls::ObjectBuffer<MappedType> defaultMapped;
8869 AllocatorTraits::construct(alloc, defaultMapped.address(),
8871 args_01),
8873 args_02),
8875 args_03),
8877 args_04),
8879 args_05),
8881 args_06),
8883 args_07),
8885 args_08),
8887 args_09));
8888 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
8889
8890 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8891 MoveUtil::move(key),
8892 defaultMapped.object());
8893#endif
8894
8895 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
8896 nodeProctor(&d_parameters.nodeFactory(), hint);
8897 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
8898 nodeProctor.release();
8899 ++d_size;
8900
8901 *isInsertedFlag = true;
8902 return hint;
8903}
8904#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 9
8905
8906#if BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 10
8907template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
8908template <class ARGS_01,
8909 class ARGS_02,
8910 class ARGS_03,
8911 class ARGS_04,
8912 class ARGS_05,
8913 class ARGS_06,
8914 class ARGS_07,
8915 class ARGS_08,
8916 class ARGS_09,
8917 class ARGS_10>
8918inline
8920HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
8921 bool *isInsertedFlag,
8924 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01,
8925 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02,
8926 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03,
8927 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04,
8928 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05,
8929 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06,
8930 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07,
8931 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08,
8932 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09,
8933 BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10)
8934{
8935 typedef bslalg::HashTableImpUtil ImpUtil;
8936
8937 const KeyType& lvalue = key;
8938 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
8939
8940 if (!hint
8941 || !d_parameters.comparator()(lvalue,
8942 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
8943 hint = this->find(lvalue, hashCode);
8944 }
8945
8946 if (hint) {
8947 *isInsertedFlag = false;
8948 return hint;
8949 }
8950
8951 if (d_size >= d_capacity) {
8952 this->rehashForNumBuckets(numBuckets() * 2);
8953 }
8954
8955#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
8956 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
8957 std::piecewise_construct,
8958 std::forward_as_tuple(MoveUtil::move(key)),
8959 std::forward_as_tuple(
8961 args_01),
8963 args_02),
8965 args_03),
8967 args_04),
8969 args_05),
8971 args_06),
8973 args_07),
8975 args_08),
8977 args_09),
8979 args_10)));
8980#else
8981 typedef typename ValueType::second_type MappedType;
8982
8983
8984 AllocatorType alloc = this->allocator();
8985
8986 bsls::ObjectBuffer<MappedType> defaultMapped;
8987 AllocatorTraits::construct(alloc, defaultMapped.address(),
8989 args_01),
8991 args_02),
8993 args_03),
8995 args_04),
8997 args_05),
8999 args_06),
9001 args_07),
9003 args_08),
9005 args_09),
9007 args_10));
9008 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
9009
9010 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
9011 MoveUtil::move(key),
9012 defaultMapped.object());
9013#endif
9014
9015 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
9016 nodeProctor(&d_parameters.nodeFactory(), hint);
9017 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
9018 nodeProctor.release();
9019 ++d_size;
9020
9021 *isInsertedFlag = true;
9022 return hint;
9023}
9024#endif // BSLSTL_HASHTABLE_VARIADIC_LIMIT_G >= 10
9025
9026#else
9027// The generated code below is a workaround for the absence of perfect
9028// forwarding in some compilers.
9029template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9030template <class... ARGS>
9031inline
9033HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
9034 bool *isInsertedFlag,
9036 const KeyType& key,
9038{
9039 typedef bslalg::HashTableImpUtil ImpUtil;
9040
9041 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
9042
9043 if (!hint
9044 || !d_parameters.comparator()(key,
9045 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
9046 hint = this->find(key, hashCode);
9047 }
9048
9049 if (hint) {
9050 *isInsertedFlag = false;
9051 return hint;
9052 }
9053
9054 if (d_size >= d_capacity) {
9055 this->rehashForNumBuckets(numBuckets() * 2);
9056 }
9057
9058#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
9059 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
9060 std::piecewise_construct,
9061 std::forward_as_tuple(key),
9062 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...));
9063#else
9064 typedef typename ValueType::second_type MappedType;
9065
9066
9067 AllocatorType alloc = this->allocator();
9068
9069 bsls::ObjectBuffer<MappedType> defaultMapped;
9070 AllocatorTraits::construct(alloc, defaultMapped.address(),
9072 args)...);
9073 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
9074
9075 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
9076 key,
9077 defaultMapped.object());
9078#endif
9079
9080 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
9081 nodeProctor(&d_parameters.nodeFactory(), hint);
9082 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
9083 nodeProctor.release();
9084 ++d_size;
9085
9086 *isInsertedFlag = true;
9087 return hint;
9088}
9089
9090
9091template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9092template <class... ARGS>
9093inline
9095HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::tryEmplace(
9096 bool *isInsertedFlag,
9100{
9101 typedef bslalg::HashTableImpUtil ImpUtil;
9102
9103 const KeyType& lvalue = key;
9104 const size_t hashCode = this->d_parameters.hashCodeForKey(key);
9105
9106 if (!hint
9107 || !d_parameters.comparator()(lvalue,
9108 ImpUtil::extractKey<KEY_CONFIG>(hint))) {
9109 hint = this->find(lvalue, hashCode);
9110 }
9111
9112 if (hint) {
9113 *isInsertedFlag = false;
9114 return hint;
9115 }
9116
9117 if (d_size >= d_capacity) {
9118 this->rehashForNumBuckets(numBuckets() * 2);
9119 }
9120
9121#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
9122 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
9123 std::piecewise_construct,
9124 std::forward_as_tuple(MoveUtil::move(key)),
9125 std::forward_as_tuple(
9127 args)...));
9128#else
9129 typedef typename ValueType::second_type MappedType;
9130
9131
9132 AllocatorType alloc = this->allocator();
9133
9134 bsls::ObjectBuffer<MappedType> defaultMapped;
9135 AllocatorTraits::construct(alloc, defaultMapped.address(),
9137 args)...);
9138 bslma::DestructorGuard<MappedType> mappedGuard(defaultMapped.address());
9139
9140 hint = d_parameters.nodeFactory().emplaceIntoNewNode(
9141 MoveUtil::move(key),
9142 defaultMapped.object());
9143#endif
9144
9145 HashTable_NodeProctor<typename ImplParameters::NodeFactory>
9146 nodeProctor(&d_parameters.nodeFactory(), hint);
9147 ImpUtil::insertAtFrontOfBucket(&d_anchor, hint, hashCode);
9148 nodeProctor.release();
9149 ++d_size;
9150
9151 *isInsertedFlag = true;
9152 return hint;
9153}
9154// }}} END GENERATED CODE
9155#endif
9156
9157// ACCESSORS
9158template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9159inline
9160ALLOCATOR HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::
9161 allocator() const
9162{
9163 return d_parameters.nodeFactory().allocator();
9164}
9165
9166template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9167inline
9169HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::bucketAtIndex(
9170 SizeType index) const
9171{
9172 BSLS_ASSERT_SAFE(index < this->numBuckets());
9173
9174 return d_anchor.bucketArrayAddress()[index];
9175}
9176
9177template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9178inline
9179typename HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::SizeType
9180HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::bucketIndexForKey(
9181 const KeyType& key) const
9182{
9183 typedef typename
9184 HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::SizeType SizeType;
9185
9186 // The following cast will not discard any useful bits, unless 'SizeType'
9187 // is larger than 'size_t', as the bucket computation takes a mod on the
9188 // supplied number of buckets. We use the following 'BSLMF_ASSERT' to
9189 // assert that assumption at compile time.
9190
9191 BSLMF_ASSERT(sizeof(SizeType) <= sizeof(size_t));
9192
9193 size_t hashCode = this->d_parameters.hashCodeForKey(key);
9194 return static_cast<SizeType>(bslalg::HashTableImpUtil::computeBucketIndex(
9195 hashCode,
9196 d_anchor.bucketArraySize()));
9197}
9198
9199template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9200inline
9201const COMPARATOR&
9202HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::comparator() const
9203{
9204 return d_parameters.originalComparator();
9205}
9206
9207template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9208inline
9209typename HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::SizeType
9210HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::countElementsInBucket(
9211 SizeType index) const
9212{
9213 BSLS_ASSERT_SAFE(index < this->numBuckets());
9214
9215 return static_cast<SizeType>(bucketAtIndex(index).countElements());
9216}
9217
9218template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9219inline
9221HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::elementListRoot() const
9222{
9223 return d_anchor.listRootAddress();
9224}
9225
9226template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9227inline
9229HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::find(
9230 const KeyType& key) const
9231{
9232 return bslalg::HashTableImpUtil::find<KEY_CONFIG>(
9233 d_anchor,
9234 key,
9235 d_parameters.comparator(),
9236 d_parameters.hashCodeForKey(key));
9237}
9238
9239template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9241HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::findEndOfRange(
9242 bslalg::BidirectionalLink *first) const
9243{
9244 BSLS_ASSERT_SAFE(first);
9245
9246 typedef bslalg::HashTableImpUtil ImpUtil;
9247
9248 // The reference to the Key passed to the functor is only optionally
9249 // const-qualified. We must be sure to hold a reference with the correct
9250 // qualification.
9251
9252 typedef
9254 KeyRef;
9255 KeyRef k = ImpUtil::extractKey<KEY_CONFIG>(first);
9256
9257 while (0 != (first = first->nextLink()) &&
9258 d_parameters.comparator()(k,ImpUtil::extractKey<KEY_CONFIG>(first)))
9259 {
9260 // This loop body is intentionally left blank.
9261 }
9262 return first;
9263}
9264
9265template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9266inline
9267void
9268HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::findRange(
9271 const KeyType& key) const
9272{
9273 BSLS_ASSERT_SAFE(first);
9274 BSLS_ASSERT_SAFE(last);
9275
9276 *first = this->find(key);
9277 *last = *first ? this->findEndOfRange(*first) : 0;
9278}
9279
9280template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9281bool
9282HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::hasSameValue(
9283 const HashTable& other) const
9284{
9285 // TBD: The template bloat of this function can be significantly reduced.
9286 //..
9287 // What matters is that the two hash tables:
9288 // i/ are the same size
9289 // ii/ have lists that are permutations of each other according to the
9290 // element's 'operator=='
9291 // This means that the implementation should be independent of all four
9292 // template parameters, but will depend on VALUE_TYPE deduced from the
9293 // KEY_CONFIG. Otherwise, after the initial size comparison, the rest
9294 // depends only on the anchors.
9295 //..
9296
9297 typedef typename KEY_CONFIG::ValueType ValueType;
9298 typedef typename ::bsl::allocator_traits<ALLOCATOR>::size_type SizeType;
9299 typedef bslalg::HashTableImpUtil ImpUtil;
9300
9301 // First test - are the containers the same size?
9302
9303 if (this->size() != other.size()) {
9304 return false; // RETURN
9305 }
9306 bslalg::BidirectionalLink *cursor = this->elementListRoot();
9307 if (!cursor) { // containers are the same size, and empty.
9308 return true; // RETURN
9309 }
9310
9311 while (cursor) {
9312 bslalg::BidirectionalLink *rhsFirst =
9313 ImpUtil::find<KEY_CONFIG>(other.d_anchor,
9314 ImpUtil::extractKey<KEY_CONFIG>(cursor),
9315 other.d_parameters.comparator(),
9316 other.d_parameters.hashCodeForKey(
9317 ImpUtil::extractKey<KEY_CONFIG>(cursor)));
9318 if (!rhsFirst) {
9319 return false; // no matching key // RETURN
9320 }
9321
9322 bslalg::BidirectionalLink *endRange = this->findEndOfRange(cursor);
9323 bslalg::BidirectionalLink *rhsLast = other.findEndOfRange(rhsFirst);
9324
9325 // Check the key-groups have the same length - a quick-fail test.
9326
9327 bslalg::BidirectionalLink *endWalker = cursor->nextLink();
9328 bslalg::BidirectionalLink *rhsWalker = rhsFirst->nextLink();
9329
9330 while (endWalker != endRange) {
9331
9332 if (rhsWalker == rhsLast) {
9333 return false; // different length subsequences // RETURN
9334 }
9335 endWalker = endWalker->nextLink();
9336 rhsWalker = rhsWalker->nextLink();
9337 }
9338
9339 if (rhsWalker != rhsLast) {
9340 return false; // different length subsequences // RETURN
9341 }
9342
9343 // Efficiently compare identical prefixes: O[N] if sequences have the
9344 // same elements in the same order. Note that comparison of values in
9345 // nodes is tested using 'operator==' and not the key-equality
9346 // comparator stored in the hash table.
9347
9348 while (cursor != endRange &&
9349 (ImpUtil::extractValue<KEY_CONFIG>(cursor) ==
9350 ImpUtil::extractValue<KEY_CONFIG>(rhsFirst)))
9351 {
9352 cursor = cursor->nextLink();
9353 rhsFirst = rhsFirst->nextLink();
9354 }
9355
9356 if (cursor == endRange) {
9357 continue; // CONTINUE
9358 }
9359
9360 // Now comes the harder part of validating that one subsequence is a
9361 // permutation of another, by counting elements that compare equal
9362 // using the equality operator, 'operator=='. Note that this code
9363 // could be simplified for hash-tables with unique keys, as we can omit
9364 // the counting-scan, and merely test for any match within the 'other'
9365 // range. Trade off the ease of a single well-tested code path, vs.
9366 // the importance of an efficient 'operator==' for hash containers.
9367 // This is currently the only place the hash-table would care about
9368 // uniqueness, and risk different hash-table types for unique- vs.
9369 // multi-containers. Note again that comparison of values in nodes is
9370 // tested using 'operator==' and not the key-equality comparator stored
9371 // in the hash tables.
9372
9373 for (bslalg::BidirectionalLink *marker = cursor;
9374 marker != endRange;
9375 marker = marker->nextLink())
9376 {
9377 const ValueType& valueAtMarker =
9378 ImpUtil::extractValue<KEY_CONFIG>(marker);
9379
9380 if (cursor != marker) { // skip on first pass only
9381 // Check if the value at 'marker' has already be seen.
9382
9383 bslalg::BidirectionalLink *scanner = cursor;
9384 while (scanner != marker &&
9385 ImpUtil::extractValue<KEY_CONFIG>(scanner) != valueAtMarker) {
9386 scanner = scanner->nextLink();
9387 }
9388 if (scanner != marker) { // We have seen 'lhs' one before.
9389 continue; // CONTINUE
9390 }
9391 }
9392
9393 SizeType matches = 0;
9394 for (bslalg::BidirectionalLink *scanner = rhsFirst;
9395 scanner != rhsLast;
9396 scanner = scanner->nextLink()) {
9397 if (ImpUtil::extractValue<KEY_CONFIG>(scanner) ==
9398 valueAtMarker) {
9399 ++matches;
9400 }
9401 }
9402 if (!matches) {
9403 return false; // RETURN
9404 }
9405
9406 // Remember, *scanner is by definition a good match
9407
9408 for (bslalg::BidirectionalLink *scanner = marker->nextLink();
9409 scanner != endRange;
9410 scanner = scanner->nextLink()) {
9411
9412 if (ImpUtil::extractValue<KEY_CONFIG>(scanner) ==
9413 valueAtMarker) {
9414 if (!--matches) { // equal matches, but excluding initial
9415 return false; // RETURN
9416 }
9417 }
9418 }
9419 if (1 != matches) {
9420 return false; // RETURN
9421 }
9422 }
9423 cursor = endRange;
9424 }
9425 return true;
9426}
9427
9428template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9429inline
9430const HASHER&
9431HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::hasher() const
9432{
9433 return d_parameters.originalHasher();
9434}
9435
9436template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9437inline
9438float HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::loadFactor() const
9439{
9440 return static_cast<float>(static_cast<double>(this->size())
9441 / static_cast<double>(this->numBuckets()));
9442}
9443
9444template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9445inline
9446float
9447HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::maxLoadFactor() const
9448{
9449 return d_maxLoadFactor;
9450}
9451
9452template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9453inline
9454typename HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::SizeType
9455HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::maxNumBuckets() const
9456{
9457 // This estimate is still on the high side, we should actually pick the
9458 // preceding entry from our table of prime numbers used for valid bucket
9459 // array sizes. There is no easy way to find that value at the moment
9460 // though.
9461
9462 typedef typename AllocatorTraits::
9463 template rebind_traits<bslalg::HashTableBucket>
9464 BucketAllocatorTraits;
9465 typedef typename BucketAllocatorTraits::allocator_type BucketAllocator;
9466
9467 return BucketAllocatorTraits::max_size(BucketAllocator(this->allocator()));
9468}
9469
9470template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9471inline
9472typename HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::SizeType
9473HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::maxSize() const
9474{
9475 return AllocatorTraits::max_size(this->allocator()) / sizeof(NodeType);
9476}
9477
9478template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9479inline
9480typename HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::SizeType
9481HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::numBuckets() const
9482{
9483 return static_cast<SizeType>(d_anchor.bucketArraySize());
9484}
9485
9486template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9487inline
9488typename HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::SizeType
9489HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::rehashThreshold() const
9490{
9491 return d_capacity;
9492}
9493
9494template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9495inline
9496typename HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::SizeType
9497HashTable<KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR>::size() const
9498{
9499 return d_size;
9500}
9501
9502} // close package namespace
9503
9504//-----------------------------------------------------------------------------
9505// free functions and operators
9506//-----------------------------------------------------------------------------
9507
9508template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9509inline
9510void
9513{
9515 TableType;
9516
9518 || a.allocator() == b.allocator()) {
9519 a.swap(b);
9520 }
9521 else {
9522 // C++11 behavior: undefined for unequal allocators
9523 // BSLS_ASSERT(allocator() == other.allocator());
9524
9525 TableType aCopy(a, b.allocator());
9526 TableType bCopy(b, a.allocator());
9527
9528 b.swap(aCopy);
9529 a.swap(bCopy);
9530 }
9531}
9532
9533template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9534inline
9538{
9539 return lhs.hasSameValue(rhs);
9540}
9541
9542template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9543inline
9547{
9548 return !(a == b);
9549}
9550
9551template <class FUNCTOR>
9552inline
9555{
9556 a.swap(b);
9557}
9558
9559template <class FUNCTOR>
9560inline
9563{
9564 a.swap(b);
9565}
9566
9567// ============================================================================
9568// TYPE TRAITS
9569// ============================================================================
9570
9571// Type traits for HashTable:
9572//: o A HashTable is bitwise movable if the both functors and the allocator are
9573//: bitwise movable.
9574//: o A HashTable uses 'bslma' allocators if the parameterized 'ALLOCATOR' is
9575//: convertible from 'bslma::Allocator*'.
9576
9577namespace bslma {
9578
9579template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9580struct UsesBslmaAllocator<bslstl::HashTable<KEY_CONFIG,
9581 HASHER,
9582 COMPARATOR,
9583 ALLOCATOR> >
9584 : bsl::is_convertible<Allocator*, ALLOCATOR>::type {
9585};
9586
9587template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9588struct UsesBslmaAllocator<bslstl::HashTable_ImplParameters<KEY_CONFIG,
9589 HASHER,
9590 COMPARATOR,
9591 ALLOCATOR> >
9592 : bsl::is_convertible<Allocator*, ALLOCATOR>::type {
9593};
9594
9595} // close namespace bslma
9596
9597namespace bslmf {
9598
9599template <class KEY_CONFIG, class HASHER, class COMPARATOR, class ALLOCATOR>
9600struct IsBitwiseMoveable<bslstl::HashTable<KEY_CONFIG,
9601 HASHER,
9602 COMPARATOR,
9603 ALLOCATOR> >
9604: bsl::integral_constant< bool, bslmf::IsBitwiseMoveable<HASHER>::value
9605 && bslmf::IsBitwiseMoveable<COMPARATOR>::value
9606 && bslmf::IsBitwiseMoveable<ALLOCATOR>::value>
9607{};
9608
9609} // close namespace bslmf
9610
9611
9612#else // if ! defined(DEFINED_BSLSTL_HASHTABLE_H)
9613# error Not valid except when included from bslstl_hashtable.h
9614#endif // ! defined(COMPILING_BSLSTL_HASHTABLE_H)
9615
9616#endif // ! defined(INCLUDED_BSLSTL_HASHTABLE_CPP03)
9617
9618// ----------------------------------------------------------------------------
9619// Copyright 2013 Bloomberg Finance L.P.
9620//
9621// Licensed under the Apache License, Version 2.0 (the "License");
9622// you may not use this file except in compliance with the License.
9623// You may obtain a copy of the License at
9624//
9625// http://www.apache.org/licenses/LICENSE-2.0
9626//
9627// Unless required by applicable law or agreed to in writing, software
9628// distributed under the License is distributed on an "AS IS" BASIS,
9629// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9630// See the License for the specific language governing permissions and
9631// limitations under the License.
9632// ----------------------------- END-OF-FILE ----------------------------------
9633
9634/** @} */
9635/** @} */
9636/** @} */
Definition bslma_bslallocator.h:588
Definition bslalg_bidirectionalnode.h:357
Definition bslalg_functoradapter.h:230
HashTable_HashWrapper< CallableVariable< HASHER >::type > Type
This typedef is an alias for the functor.
Definition bslalg_functoradapter.h:236
Definition bslalg_hashtableanchor.h:542
BidirectionalLink * listRootAddress() const
Return the value listRootAddress attribute of this object.
Definition bslalg_hashtableanchor.h:695
void setBucketArrayAddressAndSize(HashTableBucket *bucketArrayAddress, std::size_t bucketArraySize)
Definition bslalg_hashtableanchor.h:666
std::size_t bucketArraySize() const
Return the value of the bucketArraySize attribute of this object.
Definition bslalg_hashtableanchor.h:701
void swap(HashTableAnchor &other)
Definition bslalg_hashtableanchor.h:688
void setListRootAddress(BidirectionalLink *value)
Definition bslalg_hashtableanchor.h:678
HashTableBucket * bucketArrayAddress() const
Definition bslalg_hashtableanchor.h:707
Definition bslma_allocator.h:545
Definition bslma_destructorguard.h:132
Definition bslmf_movableref.h:752
~HashTable_ArrayProctor()
Definition bslstl_hashtable.h:3663
void release()
Definition bslstl_hashtable.h:3682
Definition bslstl_hashtable.h:1763
void swap(HashTable_ComparatorWrapper &other)
Exchange the value of this object with the specified other object.
Definition bslstl_hashtable.h:3545
const FUNCTOR & functor() const
Definition bslstl_hashtable.h:3537
HashTable_ComparatorWrapper()
Definition bslstl_hashtable.h:3513
bool operator()(ARG1_TYPE &arg1, ARG2_TYPE &arg2) const
Definition bslstl_hashtable.h:3530
Definition bslstl_hashtable.h:1632
const FUNCTOR & functor() const
Definition bslstl_hashtable.h:3437
HashTable_HashWrapper()
Definition bslstl_hashtable.h:3414
std::size_t operator()(ARG_TYPE &arg) const
Definition bslstl_hashtable.h:3430
void swap(HashTable_HashWrapper &other)
Exchange the value of this object with the specified other object.
Definition bslstl_hashtable.h:3444
std::size_t hashCodeForKey(DEDUCED_KEY &key) const
Definition bslstl_hashtable.h:3878
HashTable< KEY_CONFIG, HASHER, COMPARATOR, ALLOCATOR > HashTableType
Definition bslstl_hashtable.h:3288
NodeFactory & nodeFactory()
Definition bslstl_hashtable.h:3821
void quickSwapRetainAllocators(HashTable_ImplParameters *other)
Definition bslstl_hashtable.h:3845
const BaseComparator & comparator() const
Definition bslstl_hashtable.h:3866
BidirectionalNodePool< typename HashTableType::ValueType, NodeAllocator > NodeFactory
Definition bslstl_hashtable.h:3295
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASHER, LOOKUP_KEY >::value, std::size_t >::type hashCodeForTransparentKey(const LOOKUP_KEY &key) const
Definition bslstl_hashtable.h:3383
const BaseHasher & hasher() const
Definition bslstl_hashtable.h:3889
void quickSwapExchangeAllocators(HashTable_ImplParameters *other)
Definition bslstl_hashtable.h:3829
ReboundTraits::allocator_type NodeAllocator
Definition bslstl_hashtable.h:3291
HashTableType::AllocatorTraits::template rebind_traits< NodeType > ReboundTraits
Definition bslstl_hashtable.h:3290
const HASHER & originalHasher() const
Definition bslstl_hashtable.h:3923
const COMPARATOR & originalComparator() const
Definition bslstl_hashtable.h:3913
~HashTable_NodeProctor()
Definition bslstl_hashtable.h:3629
void release()
Definition bslstl_hashtable.h:3639
Definition bslstl_hashtable.h:1934
bslalg::BidirectionalLink * insertOrAssign(bool *isInsertedFlag, bslalg::BidirectionalLink *hint, BSLS_COMPILERFEATURES_FORWARD_REF(KEY_ARG) key, BDE_OTHER_TYPE &&obj)
Definition bslstl_hashtable.h:4743
bslalg::BidirectionalNode< ValueType > NodeType
Definition bslstl_hashtable.h:1942
HashTable & operator=(const HashTable &rhs)
Definition bslstl_hashtable.h:4418
KEY_CONFIG::KeyType KeyType
Definition bslstl_hashtable.h:1940
void rehashForNumBuckets(SizeType newNumBuckets)
Definition bslstl_hashtable.h:4791
ALLOCATOR AllocatorType
Definition bslstl_hashtable.h:1938
void setMaxLoadFactor(float newMaxLoadFactor)
Definition bslstl_hashtable.h:4878
void swap(HashTable &other)
Definition bslstl_hashtable.h:4901
ALLOCATOR allocator() const
Definition bslstl_hashtable.h:5058
SizeType countElementsInBucket(SizeType index) const
Definition bslstl_hashtable.h:5107
bslalg::BidirectionalLink * tryEmplace(bool *isInsertedFlag, bslalg::BidirectionalLink *hint, const KeyType &key, ARGS &&... args)
Definition bslstl_hashtable.h:4923
SizeType rehashThreshold() const
Definition bslstl_hashtable.h:5386
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASHER, LOOKUP_KEY >::value &&BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, bslalg::BidirectionalLink * >::type insertIfMissingTransparent(bool *isInsertedFlag, BSLS_COMPILERFEATURES_FORWARD_REF(LOOKUP_KEY) value)
Definition bslstl_hashtable.h:2413
bslalg::BidirectionalLink * emplaceIfMissing(bool *isInsertedFlag, Args &&... arguments)
::bsl::allocator_traits< AllocatorType > AllocatorTraits
Definition bslstl_hashtable.h:1939
bool hasSameValue(const HashTable &other) const
Definition bslstl_hashtable.h:5179
const COMPARATOR & comparator() const
Definition bslstl_hashtable.h:5099
float maxLoadFactor() const
Definition bslstl_hashtable.h:5344
bslalg::BidirectionalLink * emplace(Args &&... arguments)
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASHER, LOOKUP_KEY >::value &&BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, void >::type findRange(bslalg::BidirectionalLink **first, bslalg::BidirectionalLink **last, const LOOKUP_KEY &key) const
Definition bslstl_hashtable.h:2894
bslalg::BidirectionalLink * insert(BSLS_COMPILERFEATURES_FORWARD_REF(SOURCE_TYPE) value)
Definition bslstl_hashtable.h:4721
const HASHER & hasher() const
Definition bslstl_hashtable.h:5328
bslalg::BidirectionalLink * findEndOfRange(bslalg::BidirectionalLink *first) const
Definition bslstl_hashtable.h:5138
bslalg::BidirectionalLink * emplaceWithHint(bslalg::BidirectionalLink *hint, Args &&... arguments)
AllocatorTraits::size_type SizeType
Definition bslstl_hashtable.h:1943
void reserveForNumElements(SizeType numElements)
Definition bslstl_hashtable.h:4852
SizeType maxSize() const
Definition bslstl_hashtable.h:5370
bslalg::BidirectionalLink * remove(bslalg::BidirectionalLink *node)
Definition bslstl_hashtable.h:4813
SizeType numBuckets() const
Return the number of buckets contained in this hash table.
Definition bslstl_hashtable.h:5378
SizeType maxNumBuckets() const
Definition bslstl_hashtable.h:5352
bsl::remove_const< KeyType >::type NonConstKeyType
Definition bslstl_hashtable.h:1944
HashTable(const ALLOCATOR &basicAllocator=ALLOCATOR())
Definition bslstl_hashtable.h:3936
bslalg::BidirectionalLink * insertIfMissing(const KeyType &key)
Definition bslstl_hashtable.h:4619
~HashTable()
Destroy this object.
Definition bslstl_hashtable.h:4085
SizeType bucketIndexForKey(const KeyType &key) const
Definition bslstl_hashtable.h:5077
bslalg::BidirectionalLink * elementListRoot() const
Definition bslstl_hashtable.h:5118
SizeType size() const
Return the number of elements in this hash table.
Definition bslstl_hashtable.h:5394
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< HASHER, LOOKUP_KEY >::value &&BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, bslalg::BidirectionalLink * >::type insertOrAssignTransparent(bool *isInsertedFlag, bslalg::BidirectionalLink *hint, LOOKUP_KEY &&key, BDE_OTHER_TYPE &&obj)
Definition bslstl_hashtable.h:2527
KEY_CONFIG::ValueType ValueType
Definition bslstl_hashtable.h:1941
float loadFactor() const
Definition bslstl_hashtable.h:5335
const bslalg::HashTableBucket & bucketAtIndex(SizeType index) const
Definition bslstl_hashtable.h:5066
void removeAll()
Definition bslstl_hashtable.h:4834
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2343
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2349
#define BSLS_PERFORMANCEHINT_PREDICT_LIKELY(expr)
Definition bsls_performancehint.h:451
bool operator!=(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
bool operator==(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
void swap(OptionValue &a, OptionValue &b)
bsl::size_t size(const TYPE &array)
Return the number of elements in the specified array.
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
ALLOCATOR & lhs
Definition bslstl_string.h:3917
BSLS_KEYWORD_CONSTEXPR CONTAINER::value_type * data(CONTAINER &container)
Definition bslstl_iterator.h:1325
Definition baljsn_encoder_testtypes.h:76
Definition bdlbb_blob.h:579
Definition bslstl_algorithm.h:84
void swap(BidirectionalNodePool< VALUE, ALLOCATOR > &a, BidirectionalNodePool< VALUE, ALLOCATOR > &b)
bool operator==(const BidirectionalIterator< T1, ITER_IMP, TAG_TYPE > &lhs, const BidirectionalIterator< T2, ITER_IMP, TAG_TYPE > &rhs)
bool operator!=(const BidirectionalIterator< T1, ITER_IMP, TAG_TYPE > &lhs, const BidirectionalIterator< T2, ITER_IMP, TAG_TYPE > &rhs)
t_TYPE & type
This typedef defines the return type of this meta function.
Definition bslmf_addlvaluereference.h:131
Definition bslma_allocatortraits.h:1089
BloombergLP::bslma::AllocatorTraits_SizeType< ALLOCATOR_TYPE >::type size_type
Definition bslma_allocatortraits.h:1196
Definition bslmf_conditional.h:123
Definition bslmf_enableif.h:530
Definition bslmf_integralconstant.h:261
Definition bslmf_isconvertible.h:875
Definition bslmf_isfunction.h:232
Definition bslmf_ispointer.h:138
t_TYPE type
This typedef is an alias to the (template parameter) t_TYPE.
Definition bslmf_removeconst.h:164
Definition bslalg_hashtablebucket.h:297
Definition bslalg_hashtableimputil.h:615
static void insertAtFrontOfBucket(HashTableAnchor *anchor, BidirectionalLink *link, std::size_t hashCode)
static void remove(HashTableAnchor *anchor, BidirectionalLink *link, std::size_t hashCode)
static void insertAtBackOfBucket(HashTableAnchor *anchor, BidirectionalLink *link, std::size_t hashCode)
static std::size_t computeBucketIndex(std::size_t hashCode, std::size_t numBuckets)
Definition bslalg_hashtableimputil.h:858
static void deallocateObject(const t_ALLOCATOR &allocator, t_POINTER p, std::size_t n=1)
Definition bslma_allocatorutil.h:949
Definition bslmf_movableref.h:795
bsl::conditional< bsl::is_function< CALLABLE >::value, typenamebsl::add_lvalue_reference< CALLABLE >::type, CALLABLE >::type type
Definition bslstl_hashtable.h:1611
static bslma::Allocator * incidentalAllocator()
static bslalg::HashTableBucket * defaultBucketAddress()
static size_t nextPrime(size_t n)
static size_t growBucketsForLoadFactor(size_t *capacity, size_t minElements, size_t requestedBuckets, double maxLoadFactor)
static void destroyBucketArray(bslalg::HashTableBucket *data, std::size_t bucketArraySize, const ALLOCATOR &allocator)
Definition bslstl_hashtable.h:3717
static void initAnchor(bslalg::HashTableAnchor *anchor, std::size_t bucketArraySize, const ALLOCATOR &allocator)
Definition bslstl_hashtable.h:3743
static void assertNotNullPointer(TYPE &)
Definition bslstl_hashtable.h:3693
Definition bsls_objectbuffer.h:277
TYPE * address()
Definition bsls_objectbuffer.h:335
TYPE & object()
Definition bsls_objectbuffer.h:352