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