BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_map.h
Go to the documentation of this file.
1/// @file bslstl_map.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_map.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_MAP
9#define INCLUDED_BSLSTL_MAP
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_map bslstl_map
15/// @brief Provide an STL-compliant map class.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_map
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_map-purpose"> Purpose</a>
25/// * <a href="#bslstl_map-classes"> Classes </a>
26/// * <a href="#bslstl_map-description"> Description </a>
27/// * <a href="#bslstl_map-requirements-on-key-and-value"> Requirements on KEY and VALUE </a>
28/// * <a href="#bslstl_map-glossary"> Glossary </a>
29/// * <a href="#bslstl_map-key-comparison"> Key Comparison </a>
30/// * <a href="#bslstl_map-memory-allocation"> Memory Allocation </a>
31/// * <a href="#bslstl_map-bslma-style-allocators"> bslma-Style Allocators </a>
32/// * <a href="#bslstl_map-operations"> Operations </a>
33/// * <a href="#bslstl_map-usage"> Usage </a>
34/// * <a href="#bslstl_map-example-1-creating-a-trade-matching-system"> Example 1: Creating a Trade Matching System </a>
35///
36/// # Purpose {#bslstl_map-purpose}
37/// Provide an STL-compliant map class.
38///
39/// # Classes {#bslstl_map-classes}
40///
41/// - bsl::map: STL-compliant map template
42///
43/// **Canonical header:** bsl_map.h
44///
45/// @see bslstl_multimap, bslstl_set
46///
47/// # Description {#bslstl_map-description}
48/// This component defines a single class template `bsl::map`,
49/// implementing the standard container holding an ordered sequence of key-value
50/// pairs (having unique keys), and presenting a mapping from the keys (of a
51/// template parameter type, `KEY`) to their associated values (of another
52/// template parameter type, `VALUE`).
53///
54/// An instantiation of `map` is an allocator-aware, value-semantic type whose
55/// salient attributes are its size (number of key-value pairs) and the ordered
56/// sequence of key-value pairs the map contains. If `map` is instantiated with
57/// either a key type or mapped-value type that is not itself value-semantic,
58/// then it will not retain all of its value-semantic qualities. In particular,
59/// if either the key or value type cannot be tested for equality, then a `map`
60/// containing that type cannot be tested for equality. It is even possible to
61/// instantiate `map` with a key or mapped-value type that does not have a copy
62/// constructor, in which case the `map` will not be copyable.
63///
64/// A map meets the requirements of an associative container with bidirectional
65/// iterators in the C++ standard [associative.reqmts]. The `map` implemented
66/// here adheres to the C++11 standard when compiled with a C++11 compiler, and
67/// makes the best approximation when compiled with a C++03 compiler. In
68/// particular, for C++03 we emulate move semantics, but limit forwarding (in
69/// `emplace`) to `const` lvalues, and make no effort to emulate `noexcept` or
70/// initializer-lists.
71///
72/// ## Requirements on KEY and VALUE {#bslstl_map-requirements-on-key-and-value}
73///
74///
75/// A `map` is a fully Value-Semantic Type (see @ref bsldoc_glossary ) only if the
76/// supplied `KEY` and `VALUE` template parameters are themselves fully
77/// value-semantic. It is possible to instantiate a `map` with `KEY` and
78/// `VALUE` parameter arguments that do not provide a full set of value-semantic
79/// operations, but then some methods of the container may not be instantiable.
80/// The following terminology, adopted from the C++11 standard, is used in the
81/// function documentation of `map` to describe a function's requirements for
82/// the `KEY` and `VALUE` template parameters. These terms are also defined in
83/// sections [utility.arg.requirements] and [container.requirements.general] of
84/// the C++11 standard. Note that, in the context of a `map` instantiation, the
85/// requirements apply specifically to the map's entry type, `value_type`, which
86/// is an alias for `bsl::pair<const KEY, VALUE>`.
87///
88/// ## Glossary {#bslstl_map-glossary}
89///
90///
91/// @code
92/// Legend
93/// ------
94/// 'X' - denotes an allocator-aware container type (e.g., 'map')
95/// 'T' - 'value_type' associated with 'X'
96/// 'A' - type of the allocator used by 'X'
97/// 'm' - lvalue of type 'A' (allocator)
98/// 'p', - address ('T *') of uninitialized storage for a 'T' within an 'X'
99/// 'rv' - rvalue of type (non-'const') 'T'
100/// 'v' - rvalue or lvalue of type (possibly 'const') 'T'
101/// 'args' - 0 or more arguments
102/// @endcode
103/// The following terms are used to more precisely specify the requirements on
104/// template parameter types in function-level documentation.
105///
106/// *default-insertable*: `T` has a default constructor. More precisely, `T`
107/// is `default-insertable` into `X` means that the following expression is
108/// well-formed:
109/// `allocator_traits<A>::construct(m, p)`
110///
111/// *move-insertable*: `T` provides a constructor that takes an rvalue of type
112/// (non-`const`) `T`. More precisely, `T` is `move-insertable` into `X`
113/// means that the following expression is well-formed:
114/// `allocator_traits<A>::construct(m, p, rv)`
115///
116/// *copy-insertable*: `T` provides a constructor that takes an lvalue or
117/// rvalue of type (possibly `const`) `T`. More precisely, `T` is
118/// `copy-insertable` into `X` means that the following expression is
119/// well-formed:
120/// `allocator_traits<A>::construct(m, p, v)`
121///
122/// *move-assignable*: `T` provides an assignment operator that takes an rvalue
123/// of type (non-`const`) `T`.
124///
125/// *copy-assignable*: `T` provides an assignment operator that takes an lvalue
126/// or rvalue of type (possibly `const`) `T`.
127///
128/// *emplace-constructible*: `T` is `emplace-constructible` into `X` from
129/// `args` means that the following expression is well-formed:
130/// `allocator_traits<A>::construct(m, p, args)`
131///
132/// *erasable*: `T` provides a destructor. More precisely, `T` is `erasable`
133/// from `X` means that the following expression is well-formed:
134/// `allocator_traits<A>::destroy(m, p)`
135///
136/// *equality-comparable*: The type provides an equality-comparison operator
137/// that defines an equivalence relationship and is both reflexive and
138/// transitive.
139///
140/// ## Key Comparison {#bslstl_map-key-comparison}
141///
142///
143/// The type supplied as a map's `COMPARATOR` template parameter determines how
144/// that map will order elements. In particular, the `COMPARATOR` type must
145/// induce a strict weak ordering on objects of type `KEY`. The `COMPARATOR`
146/// parameter defaults to `std::less<KEY>` when not supplied in an instantiation
147/// of `map`. Note that the `COMPARATOR` type must be copy-constructible.
148///
149/// The C++11 standard does not require that the function-call operator provided
150/// by `COMPARATOR` functors be `const`-qualified. However, there is a
151/// suggestion for C++17 that this is an oversight in the standard, and that
152/// `const`-qualification will be required in the future. Keep this in mind
153/// when opting to use an alternative to the default `COMPARATOR`.
154///
155/// ## Memory Allocation {#bslstl_map-memory-allocation}
156///
157///
158/// The type supplied as a map's `ALLOCATOR` template parameter determines how
159/// that map will allocate memory. The `map` template supports allocators
160/// meeting the requirements of the C++11 standard [allocator.requirements].
161/// In addition, `map` supports scoped-allocators derived from the
162/// `bslma::Allocator` memory allocation protocol. Clients intending to use
163/// `bslma`-style allocators should use the template's default `ALLOCATOR`
164/// type: The default type for the `ALLOCATOR` template parameter,
165/// `bsl::allocator`, provides a C++11 standard-compatible adapter for a
166/// `bslma::Allocator` object.
167///
168/// ### bslma-Style Allocators {#bslstl_map-bslma-style-allocators}
169///
170///
171/// If the (template parameter) type `ALLOCATOR` of a `map` instantiation' is
172/// `bsl::allocator`, then objects of that map type will conform to the standard
173/// behavior of a `bslma`-allocator-enabled type. Such a map accepts an
174/// optional `bslma::Allocator` argument at construction. If the address of a
175/// `bslma::Allocator` object is explicitly supplied at construction, it is used
176/// to supply memory for the map throughout its lifetime; otherwise, the map
177/// will use the default allocator installed at the time of the map's
178/// construction (see @ref bslma_default ). In addition to directly allocating
179/// memory from the indicated `bslma::Allocator`, a map supplies that
180/// allocator's address to the constructors of contained objects of the
181/// (template parameter) type `KEY` and `VALUE`, if respectively, the types
182/// define the `bslma::UsesBslmaAllocator` trait.
183///
184/// ## Operations {#bslstl_map-operations}
185///
186///
187/// This section describes the run-time complexity of operations on instances
188/// of `map`:
189/// @code
190/// Legend
191/// ------
192/// 'K' - (template parameter) type 'KEY' of the map
193/// 'V' - (template parameter) type 'VALUE' of the map
194/// 'a', 'b' - two distinct objects of type 'map<K, V>'
195/// 'rv' - modifiable rvalue of type 'map<K, V>'
196/// 'n', 'm' - number of elements in 'a' and 'b', respectively
197/// 'value_type' - 'pair<const K, V>'
198/// 'c' - comparator providing an ordering for objects of type 'K'
199/// 'al - STL-style memory allocator
200/// 'i1', 'i2' - two iterators defining a sequence of 'value_type' objects
201/// 'k' - object of type 'K'
202/// 'v' - object of type 'V'
203/// 'vt' - object of type 'value_type'
204/// 'rvt' - modifiable rvalue of type 'value_type'
205/// 'p1', 'p2' - two 'const_iterator's belonging to 'a'
206/// distance(i1,i2) - number of elements in the range '[i1 .. i2)'
207///
208/// +----------------------------------------------------+--------------------+
209/// | Operation | Complexity |
210/// +====================================================+====================+
211/// | map<K, V> a; (default construction) | O[1] |
212/// | map<K, V> a(al); | |
213/// | map<K, V> a(c, al); | |
214/// +----------------------------------------------------+--------------------+
215/// | map<K, V> a(rv); (move construction) | O[1] if 'a' and |
216/// | map<K, V> a(rv, al); | 'rv' use the same |
217/// | | allocator, |
218/// | | O[n] otherwise |
219/// +----------------------------------------------------+--------------------+
220/// | map<K, V> a(b); (copy construction) | O[n] |
221/// | map<K, V> a(b, al); | |
222/// +----------------------------------------------------+--------------------+
223/// | map<K, V> a(i1, i2); | O[N] if [i1 .. i2) |
224/// | map<K, V> a(i1, i2, al); | is sorted with |
225/// | map<K, V> a(i1, i2, c, al); | 'a.value_comp()', |
226/// | | O[N * log(N)] |
227/// | | otherwise, where N |
228/// | | is distance(i1,i2) |
229/// +----------------------------------------------------+--------------------+
230/// | a.~map<K, V>(); (destruction) | O[n] |
231/// +----------------------------------------------------+--------------------+
232/// | a = rv; (move assignment) | O[1] if 'a' and |
233/// | | 'rv' use the same |
234/// | | allocator, |
235/// | | O[n] otherwise |
236/// +----------------------------------------------------+--------------------+
237/// | a = b; (copy assignment) | O[n] |
238/// +----------------------------------------------------+--------------------+
239/// | a.begin(), a.end(), a.cbegin(), a.cend(), | O[1] |
240/// | a.rbegin(), a.rend(), a.crbegin(), a.crend() | |
241/// +----------------------------------------------------+--------------------+
242/// | a == b, a != b | O[n] |
243/// +----------------------------------------------------+--------------------+
244/// | a < b, a <= b, a > b, a >= b | O[n] |
245/// +----------------------------------------------------+--------------------+
246/// | a.swap(b), swap(a, b) | O[1] if 'a' and |
247/// | | 'b' use the same |
248/// | | allocator, |
249/// | | O[n + m] otherwise |
250/// +----------------------------------------------------+--------------------+
251/// | a.size() | O[1] |
252/// +----------------------------------------------------+--------------------+
253/// | a.max_size() | O[1] |
254/// +----------------------------------------------------+--------------------+
255/// | a.empty() | O[1] |
256/// +----------------------------------------------------+--------------------+
257/// | get_allocator() | O[1] |
258/// +----------------------------------------------------+--------------------+
259/// | a[k] | O[log(n)] |
260/// +----------------------------------------------------+--------------------+
261/// | a.at(k) | O[log(n)] |
262/// +----------------------------------------------------+--------------------+
263/// | a.insert(vt) | O[log(n)] |
264/// | a.insert(rvt) | |
265/// | a.emplace(Args&&...) | |
266/// +----------------------------------------------------+--------------------+
267/// | a.insert(p1, vt) | amortized constant |
268/// | a.insert(p1, rvt) | if the value is |
269/// | a.emplace(p1, Args&&...) | inserted right |
270/// | | before p1, |
271/// | | O[log(n)] |
272/// | | otherwise |
273/// +----------------------------------------------------+--------------------+
274/// | a.insert(i1, i2) | O[log(N) * |
275/// | | distance(i1,i2)] |
276/// | | |
277/// | | where N is |
278/// | | n + distance(i1,i2)|
279/// +----------------------------------------------------+--------------------+
280/// | a.erase(p1) | amortized constant |
281/// +----------------------------------------------------+--------------------+
282/// | a.erase(k) | O[log(n) + |
283/// | | a.count(k)] |
284/// +----------------------------------------------------+--------------------+
285/// | a.erase(p1, p2) | O[log(n) + |
286/// | | distance(p1, p2)] |
287/// +----------------------------------------------------+--------------------+
288/// | a.erase(p1, p2) | O[log(n) + |
289/// | | distance(p1, p2)] |
290/// +----------------------------------------------------+--------------------+
291/// | a.clear() | O[n] |
292/// +----------------------------------------------------+--------------------+
293/// | a.contains(k) | O[log(n)] |
294/// +----------------------------------------------------+--------------------+
295/// | a.key_comp() | O[1] |
296/// +----------------------------------------------------+--------------------+
297/// | a.value_comp() | O[1] |
298/// +----------------------------------------------------+--------------------+
299/// | a.find(k) | O[log(n)] |
300/// +----------------------------------------------------+--------------------+
301/// | a.count(k) | O[log(n) + |
302/// | | a.count(k)] |
303/// +----------------------------------------------------+--------------------+
304/// | a.lower_bound(k) | O[log(n)] |
305/// +----------------------------------------------------+--------------------+
306/// | a.upper_bound(k) | O[log(n)] |
307/// +----------------------------------------------------+--------------------+
308/// | a.equal_range(k) | O[log(n)] |
309/// +----------------------------------------------------+--------------------+
310/// @endcode
311///
312/// ## Usage {#bslstl_map-usage}
313///
314///
315/// In this section we show intended use of this component.
316///
317/// ### Example 1: Creating a Trade Matching System {#bslstl_map-example-1-creating-a-trade-matching-system}
318///
319///
320/// In this example, we will utilize `bsl::map` to define and implement a class,
321/// `TradeMatcher`, that provides a simple trade matching system for a single
322/// stock. The manipulators of `TradeMatcher` will allow clients to place buy
323/// orders and sell orders, and the accessors of `TradeMatcher` will allow
324/// clients to retrieve active orders and past executions.
325///
326/// First, we define the public interface for `TradeMatcher`:
327/// @code
328/// /// This class provides a mechanism that characterizes a simple trade
329/// /// matching system for one stock. An object of this class allows
330/// /// clients to place orders and view the active orders.
331/// class TradeMatcher {
332/// @endcode
333/// Here, we create two type aliases, `SellOrdersMap` and `BuyOrdersMap`, for
334/// two `bsl::map` instantiations that maps the price of an order (type
335/// `double`) to the quantity of the order (type `int`). `SellOrdersMap` uses
336/// the default `bsl::less` comparator to store the sequence of sell orders in
337/// ascending price order. `BuyOrdersMap` uses the `bsl::greater` comparator to
338/// store the sequence of buy orders in descending price order. Also note that
339/// we use the default `ALLOCATOR` template parameter for both aliases as we
340/// intend to provide memory with `bslma`-style allocators:
341/// @code
342/// // PRIVATE TYPES
343/// typedef bsl::map<double, int> SellOrdersMap;
344/// // This `typedef` is an alias for a mapping between the price and
345/// // quantity of an order in ascending price order.
346///
347/// typedef bsl::map<double, int, std::greater<double> > BuyOrdersMap;
348/// // This `typedef` is an alias for a mapping between the price and
349/// // quantity of an order in descending price order.
350///
351///
352/// // DATA
353/// SellOrdersMap d_sellOrders; // current sell orders
354/// BuyOrdersMap d_buyOrders; // current buy orders
355///
356/// private:
357/// // NOT IMPLEMENTED
358/// TradeMatcher& operator=(const TradeMatcher&);
359/// TradeMatcher(const TradeMatcher&);
360///
361/// public:
362/// // PUBLIC TYPES
363/// typedef SellOrdersMap::const_iterator SellOrdersConstIterator;
364/// // This `typedef` provides an alias for the type of an iterator
365/// // providing non-modifiable access to sell orders in a
366/// // `TradeMatcher`.
367///
368/// typedef BuyOrdersMap::const_iterator BuyOrdersConstIterator;
369/// // This `typedef` provides an alias for the type of an iterator
370/// // providing non-modifiable access to buy orders in a
371/// // `TradeMatcher`.
372///
373/// // CREATORS
374/// TradeMatcher(bslma::Allocator *basicAllocator = 0);
375/// // Create an empty `TradeMatcher` object. Optionally specify a
376/// // `basicAllocator` used to supply memory. If `basicAllocator` is
377/// // 0, the currently installed default allocator is used.
378///
379/// //! ~TradeMatcher() = default;
380/// // Destroy this object.
381///
382/// // MANIPULATORS
383/// void placeBuyOrder(double price, int numShares);
384/// // Place an order to buy the specified `numShares` at the specified
385/// // `price`. The placed buy order will (possibly partially) execute
386/// // when active sale orders exist in the system at or below `price`.
387/// // The behavior is undefined unless `0 < price` and `0 <
388/// // numShares`.
389///
390/// void placeSellOrder(double price, int numShares);
391/// // Place an order to sell the specified `numShares` at the
392/// // specified `price`. The placed sell order will (possibly
393/// // partially) execute when active buy orders exist in the system at
394/// // or above `price`. The behavior is undefined unless `0 < price`
395/// // and `0 < numShares`.
396///
397/// // ACCESSORS
398/// SellOrdersConstIterator beginSellOrders() const;
399/// // Return an iterator providing non-modifiable access to the active
400/// // sell order at the lowest price in the ordered sequence (from low
401/// // price to high price) of sell orders maintained by this object.
402///
403/// SellOrdersConstIterator endSellOrders() const;
404/// // Return an iterator providing non-modifiable access to the
405/// // past-the-end sell order in the ordered sequence (from low price
406/// // to high price) of sell orders maintained by this object.
407///
408/// BuyOrdersConstIterator beginBuyOrders() const;
409/// // Return an iterator providing non-modifiable access to the active
410/// // buy order at the highest price in the ordered sequence (from
411/// // high price to low price) of buy orders maintained by this
412/// // object.
413///
414/// BuyOrdersConstIterator endBuyOrders() const;
415/// // Return an iterator providing non-modifiable access to the
416/// // past-the-end buy order in the ordered sequence (from high price
417/// // to low price) of buy orders maintained by this object.
418/// };
419/// @endcode
420/// Now, we define the implementations methods of the `TradeMatcher` class:
421/// @code
422/// // CREATORS
423/// TradeMatcher::TradeMatcher(bslma::Allocator *basicAllocator)
424/// : d_sellOrders(basicAllocator)
425/// , d_buyOrders(basicAllocator)
426/// {
427/// }
428/// @endcode
429/// Notice that, on construction, we pass the contained `bsl::map` objects the
430/// `bsl::Allocator` supplied at construction'.
431/// @code
432/// // MANIPULATORS
433/// void TradeMatcher::placeBuyOrder(double price, int numShares)
434/// {
435/// BSLS_ASSERT(0 < price);
436/// BSLS_ASSERT(0 < numShares);
437///
438/// // Buy shares from sellers from the one with the lowest price up to but
439/// // not including the first seller with a price greater than the
440/// // specified `price`.
441///
442/// SellOrdersMap::iterator itr = d_sellOrders.begin();
443///
444/// while (numShares && itr != d_sellOrders.upper_bound(price)) {
445/// if (itr->second > numShares) {
446/// itr->second -= numShares;
447/// numShares = 0;
448/// break;
449/// }
450///
451/// itr = d_sellOrders.erase(itr);
452/// numShares -= itr->second;
453/// }
454///
455/// if (numShares > 0) {
456/// d_buyOrders[price] += numShares;
457/// }
458/// }
459///
460/// void TradeMatcher::placeSellOrder(double price, int numShares)
461/// {
462/// BSLS_ASSERT(0 < price);
463/// BSLS_ASSERT(0 < numShares);
464///
465/// // Sell shares to buyers from the one with the highest price up to but
466/// // not including the first buyer with a price smaller than the
467/// // specified `price`.
468///
469/// BuyOrdersMap::iterator itr = d_buyOrders.begin();
470///
471/// while (numShares && itr != d_buyOrders.upper_bound(price)) {
472/// if (itr->second > numShares) {
473/// itr->second -= numShares;
474/// numShares = 0;
475/// break;
476/// }
477///
478/// itr = d_buyOrders.erase(itr);
479/// numShares -= itr->second;
480/// }
481///
482/// if (numShares > 0) {
483/// d_sellOrders[price] += numShares;
484/// }
485/// }
486///
487/// // ACCESSORS
488/// TradeMatcher::SellOrdersConstIterator TradeMatcher::beginSellOrders() const
489/// {
490/// return d_sellOrders.begin();
491/// }
492///
493/// TradeMatcher::SellOrdersConstIterator TradeMatcher::endSellOrders() const
494/// {
495/// return d_sellOrders.end();
496/// }
497///
498/// TradeMatcher::BuyOrdersConstIterator TradeMatcher::beginBuyOrders() const
499/// {
500/// return d_buyOrders.begin();
501/// }
502///
503/// TradeMatcher::BuyOrdersConstIterator TradeMatcher::endBuyOrders() const
504/// {
505/// return d_buyOrders.end();
506/// }
507/// @endcode
508/// @}
509/** @} */
510/** @} */
511
512/** @addtogroup bsl
513 * @{
514 */
515/** @addtogroup bslstl
516 * @{
517 */
518/** @addtogroup bslstl_map
519 * @{
520 */
521
522#include <bslscm_version.h>
523
524#include <bslstl_algorithm.h>
525#include <bslstl_iterator.h>
526#include <bslstl_iteratorutil.h>
527#include <bslstl_mapcomparator.h>
528#include <bslstl_pair.h>
529#include <bslstl_stdexceptutil.h>
530#include <bslstl_treeiterator.h>
531#include <bslstl_treenode.h>
532#include <bslstl_treenodepool.h>
533
534#include <bslalg_rangecompare.h>
535#include <bslalg_rbtreeanchor.h>
536#include <bslalg_rbtreenode.h>
537#include <bslalg_rbtreeutil.h>
540
542#include <bslma_isstdallocator.h>
543#include <bslma_default.h>
545#include <bslma_bslallocator.h>
547
549#include <bslmf_enableif.h>
550#include <bslmf_isconvertible.h>
552#include <bslmf_movableref.h>
553#include <bslmf_typeidentity.h>
554#include <bslmf_util.h> // 'forward(V)'
555
556#include <bsls_assert.h>
558#include <bsls_keyword.h>
559#include <bsls_objectbuffer.h>
560#include <bsls_performancehint.h>
561#include <bsls_platform.h>
562#include <bsls_util.h> // 'forward<T>(V)'
563
564#include <functional>
565
566#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
567# include <initializer_list>
568#endif
569
570#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
571#include <tuple> // for forward_as_tuple (C++11)
572#include <utility> // for piecewise_construct (C++11)
573#endif
574
575#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
576#include <bsls_nativestd.h>
577#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
578
579#ifdef BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER
580#include <type_traits>
581 #ifndef BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
582 #error Rvalue references curiously absent despite native 'type_traits'.
583 #endif
584#endif
585
586#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
587// Include version that can be compiled with C++03
588// Generated on Thu Oct 21 10:11:37 2021
589// Command line: sim_cpp11_features.pl bslstl_map.h
590# define COMPILING_BSLSTL_MAP_H
591# include <bslstl_map_cpp03.h>
592# undef COMPILING_BSLSTL_MAP_H
593#else
594
595namespace bsl {
596
597 // =========
598 // class map
599 // =========
600
601/// This class template implements a value-semantic container type holding
602/// an ordered sequence of key-value pairs having unique keys that provide a
603/// mapping from keys (of the template parameter type, `KEY`) to their
604/// associated values (of another template parameter type, `VALUE`).
605///
606/// This class:
607/// * supports a complete set of *value-semantic* operations
608/// - except for BDEX serialization
609/// * is *exception-neutral*
610/// * is *alias-safe*
611/// * is `const` *thread-safe*
612/// For terminology see @ref bsldoc_glossary .
613///
614/// See @ref bslstl_map
615template <class KEY,
616 class VALUE,
617 class COMPARATOR = std::less<KEY>,
618 class ALLOCATOR = allocator<pair<const KEY, VALUE> > >
619class map {
620
621 // PRIVATE TYPES
622
623 /// This typedef is an alias for the type of key-value pair objects
624 /// maintained by this map.
626
627 /// This typedef is an alias for the comparator used internally by this
628 /// map.
629 typedef BloombergLP::bslstl::MapComparator<KEY, VALUE, COMPARATOR>
630 Comparator;
631
632 /// This typedef is an alias for the type of nodes held by the tree (of
633 /// nodes) used to implement this map.
634 typedef BloombergLP::bslstl::TreeNode<ValueType> Node;
635
636 /// This typedef is an alias for the factory type used to create and
637 /// destroy `Node` objects.
638 typedef BloombergLP::bslstl::TreeNodePool<ValueType, ALLOCATOR>
639 NodeFactory;
640
641 /// This typedef is an alias for the allocator traits type associated
642 /// with this container.
644
645 /// This typedef is a convenient alias for the utility associated with
646 /// movable references.
647 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
648
649 /// This struct is wrapper around the comparator and allocator data
650 /// members. It takes advantage of the empty-base optimization (EBO) so
651 /// that if the comparator is stateless, it takes up no space.
652 ///
653 /// TBD: This class should eventually be replaced by the use of a
654 /// general EBO-enabled component that provides a `pair`-like interface
655 /// or a `tuple`.
656 ///
657 /// See @ref bslstl_map
658 class DataWrapper : public Comparator {
659
660 // DATA
661 NodeFactory d_pool; // pool of 'Node' objects
662
663 private:
664 // NOT IMPLEMENTED
665 DataWrapper(const DataWrapper&);
666 DataWrapper& operator=(const DataWrapper&);
667
668 public:
669 // CREATORS
670
671 /// Create a data wrapper using a copy of the specified `comparator`
672 /// to order key-value pairs and a copy of the specified
673 /// `basicAllocator` to supply memory.
674 DataWrapper(const COMPARATOR& comparator,
675 const ALLOCATOR& basicAllocator);
676
677 /// Create a data wrapper initialized to the contents of the `pool`
678 /// associated with the specified `original` data wrapper. The
679 /// comparator and allocator associated with `original` are
680 /// propagated to the new data wrapper. `original` is left in a
681 /// valid but unspecified state.
682 DataWrapper(
683 BloombergLP::bslmf::MovableRef<DataWrapper> original);// IMPLICIT
684
685 // MANIPULATORS
686
687 /// Return a reference providing modifiable access to the node
688 /// factory associated with this data wrapper.
689 NodeFactory& nodeFactory();
690
691 // ACCESSORS
692
693 /// Return a reference providing non-modifiable access to the node
694 /// factory associated with this data wrapper.
695 const NodeFactory& nodeFactory() const;
696 };
697
698 // DATA
699 DataWrapper d_compAndAlloc;
700 // comparator and pool of 'Node'
701 // objects
702
703 BloombergLP::bslalg::RbTreeAnchor d_tree; // balanced tree of 'Node'
704 // objects
705
706 public:
707 // PUBLIC TYPES
708 typedef KEY key_type;
709 typedef VALUE mapped_type;
711 typedef COMPARATOR key_compare;
712 typedef ALLOCATOR allocator_type;
715
720
721 typedef BloombergLP::bslstl::TreeIterator<
723 typedef BloombergLP::bslstl::TreeIterator<
725 typedef bsl::reverse_iterator<iterator> reverse_iterator;
726 typedef bsl::reverse_iterator<const_iterator> const_reverse_iterator;
727
728 /// This nested class defines a mechanism for comparing two objects of
729 /// `value_type` by adapting an object of (template parameter) type
730 /// `COMPARATOR`, which compares two objects of (template parameter)
731 /// type `KEY` . Note that this class exactly matches its definition in
732 /// the C++11 standard [map.overview]; otherwise, we would have
733 /// implemented it as a separate component-local class.
734 ///
735 /// See @ref bslstl_map
737
738 // FRIENDS
739 friend class map;
740
741 protected:
742 // PROTECTED DATA
743 COMPARATOR comp; // we would not have elected to make this data
744 // member 'protected'
745
746 // PROTECTED CREATORS
747
748 /// Create a @ref value_compare object that uses the specified
749 /// `comparator`.
750 value_compare(COMPARATOR comparator); // IMPLICIT
751
752 public:
753 // PUBLIC TYPES
754
755 /// This `typedef` is an alias for the result type of a call to the
756 /// overload of `operator()` (the comparison function) provided by a
757 /// `map::value_compare` object.
758 typedef bool result_type;
759
760 /// This `typedef` is an alias for the type of the first parameter
761 /// of the overload of `operator()` (the comparison function)
762 /// provided by a `map::value_compare` object.
764
765 /// This `typedef` is an alias for the type of the second parameter
766 /// of the overload of `operator()` (the comparison function)
767 /// provided by a `map::value_compare` object.
769
770 // CREATORS
771 value_compare(const value_compare& original) = default;
772 // Create a @ref value_compare object having the same value as the
773 // specified 'original' object.
774
775 ~value_compare() = default;
776 // Destroy this object.
777
778 // MANIPULATORS
779 value_compare& operator=(const value_compare& rhs) = default;
780 // Assign to this object the value of the specified 'rhs' object,
781 // and return a reference providing modifiable access to this
782 // object.
783
784 // ACCESSORS
785
786 /// Return `true` if the specified `x` object is ordered before the
787 /// specified `y` object, as determined by the comparator supplied
788 /// at construction, and `false` otherwise.
789 bool operator()(const value_type& x, const value_type& y) const;
790 };
791
792 private:
793 // PRIVATE CLASS METHODS
794
795 /// Return an address providing modifiable access to the specified
796 /// `node`. The behavior is undefined unless `node` is the address of a
797 /// `Node` object.
798 static Node *toNode(BloombergLP::bslalg::RbTreeNode *node);
799
800 /// Return an address providing non-modifiable access to the specified
801 /// `node`. The behavior is undefined unless `node` is the address of a
802 /// `Node` object.
803 static const Node *toNode(const BloombergLP::bslalg::RbTreeNode *node);
804
805 // PRIVATE MANIPULATORS
806
807 /// Return a reference providing modifiable access to the node allocator
808 /// for this map.
809 NodeFactory& nodeFactory();
810
811 /// Return a reference providing modifiable access to the comparator for
812 /// this map.
813 Comparator& comparator();
814
815 /// Efficiently exchange the value, comparator, and allocator of this
816 /// object with the value, comparator, and allocator of the specified
817 /// `other` object. This method provides the no-throw exception-safety
818 /// guarantee, *unless* swapping the (user-supplied) comparator or
819 /// allocator objects can throw.
820 void quickSwapExchangeAllocators(map& other);
821
822 /// Efficiently exchange the value and comparator of this object with
823 /// the value and comparator of the specified `other` object. This
824 /// method provides the no-throw exception-safety guarantee, *unless*
825 /// swapping the (user-supplied) comparator objects can throw. The
826 /// behavior is undefined unless this object was created with the same
827 /// allocator as `other`.
828 void quickSwapRetainAllocators(map& other);
829
830 // PRIVATE ACCESSORS
831
832 /// Return a reference providing non-modifiable access to the node
833 /// allocator for this map.
834 const NodeFactory& nodeFactory() const;
835
836 /// Return a reference providing non-modifiable access to the comparator
837 /// for this map.
838 const Comparator& comparator() const;
839
840 public:
841 // CREATORS
842
844 /// Create an empty map. Optionally specify a `comparator` used to
845 /// order key-value pairs contained in this object. If `comparator` is
846 /// not supplied, a default-constructed object of the (template
847 /// parameter) type `COMPARATOR` is used. Optionally specify a
848 /// `basicAllocator` used to supply memory. If `basicAllocator` is not
849 /// supplied, a default-constructed object of the (template parameter)
850 /// type `ALLOCATOR` is used. If the type `ALLOCATOR` is
851 /// `bsl::allocator` (the default), then `basicAllocator`, if supplied,
852 /// shall be convertible to `bslma::Allocator *`. If the type
853 /// `ALLOCATOR` is `bsl::allocator` and `basicAllocator` is not
854 /// supplied, the currently installed default allocator is used.
855 explicit map(const COMPARATOR& comparator,
856 const ALLOCATOR& basicAllocator = ALLOCATOR())
857 : d_compAndAlloc(comparator, basicAllocator)
858 , d_tree()
859 {
860 // The implementation is placed here in the class definition to work
861 // around an AIX compiler bug, where the constructor can fail to
862 // compile because it is unable to find the definition of the default
863 // argument. This occurs when a parameterized class wraps around the
864 // container and the comparator is defined after the new class.
865 }
866
867 /// Create an empty map that uses the specified `basicAllocator` to
868 /// supply memory. Use a default-constructed object of the (template
869 /// parameter) type `COMPARATOR` to order the key-value pairs contained
870 /// in this map. Note that a `bslma::Allocator *` can be supplied for
871 /// `basicAllocator` if the (template parameter) `ALLOCATOR` is
872 /// `bsl::allocator` (the default).
873 explicit map(const ALLOCATOR& basicAllocator);
874
875 /// Create a map having the same value as the specified `original`
876 /// object. Use a copy of `original.key_comp()` to order the key-value
877 /// pairs contained in this map. Use the allocator returned by
878 /// 'bsl::allocator_traits<ALLOCATOR>::
879 /// select_on_container_copy_construction(original.get_allocator())' to
880 /// allocate memory. If the (template parameter) type `ALLOCATOR` is
881 /// `bsl::allocator` (the default), the currently installed default
882 /// allocator is used. This method requires that the (template
883 /// parameter) types `KEY` and `VALUE` both be `copy-insertable` into
884 /// this map (see {Requirements on `KEY` and `VALUE`}).
885 map(const map& original);
886
887 /// Create a map having the same value as the specified `original`
888 /// object by moving (in constant time) the contents of `original` to
889 /// the new map. Use a copy of `original.key_comp()` to order the
890 /// key-value pairs contained in this map. The allocator associated
891 /// with `original` is propagated for use in the newly-created map.
892 /// `original` is left in a valid but unspecified state.
893 map(BloombergLP::bslmf::MovableRef<map> original); // IMPLICIT
894
895 /// Create a map having the same value as the specified `original`
896 /// object that uses the specified `basicAllocator` to supply memory.
897 /// Use a copy of `original.key_comp()` to order the key-value pairs
898 /// contained in this map. This method requires that the (template
899 /// parameter) types `KEY` and `VALUE` both be `copy-insertable` into
900 /// this map (see {Requirements on `KEY` and `VALUE`}). Note that a
901 /// `bslma::Allocator *` can be supplied for `basicAllocator` if the
902 /// (template parameter) `ALLOCATOR` is `bsl::allocator` (the default).
903 map(const map& original,
904 const typename type_identity<ALLOCATOR>::type& basicAllocator);
905
906 /// Create a map having the same value as the specified `original`
907 /// object that uses the specified `basicAllocator` to supply memory.
908 /// The contents of `original` are moved (in constant time) to the new
909 /// map if `basicAllocator == original.get_allocator()`, and are move-
910 /// inserted (in linear time) using `basicAllocator` otherwise.
911 /// `original` is left in a valid but unspecified state. Use a copy of
912 /// `original.key_comp()` to order the key-value pairs contained in this
913 /// map. This method requires that the (template parameter) types `KEY`
914 /// and `VALUE` both be `move-insertable` into this map (see
915 /// {Requirements on `KEY` and `VALUE`}). Note that a
916 /// `bslma::Allocator *` can be supplied for `basicAllocator` if the
917 /// (template parameter) `ALLOCATOR` is `bsl::allocator` (the default).
918 map(BloombergLP::bslmf::MovableRef<map> original,
919 const typename type_identity<ALLOCATOR>::type& basicAllocator);
920
921 /// Create a map, and insert each `value_type` object in the sequence
922 /// starting at the specified `first` element, and ending immediately
923 /// before the specified `last` element, ignoring those objects having a
924 /// key equivalent to that which appears earlier in the sequence.
925 /// Optionally specify a `comparator` used to order key-value pairs
926 /// contained in this object. If `comparator` is not supplied, a
927 /// default-constructed object of the (template parameter) type
928 /// `COMPARATOR` is used. Optionally specify a `basicAllocator` used to
929 /// supply memory. If `basicAllocator` is not supplied, a
930 /// default-constructed object of the (template parameter) type
931 /// `ALLOCATOR` is used. If the type `ALLOCATOR` is `bsl::allocator`
932 /// (the default), then `basicAllocator`, if supplied, shall be
933 /// convertible to `bslma::Allocator *`. If the type `ALLOCATOR` is
934 /// `bsl::allocator` and `basicAllocator` is not supplied, the currently
935 /// installed default allocator is used. If the sequence `first` to
936 /// `last` is ordered according to `comparator`, then this operation has
937 /// `O[N]` complexity, where `N` is the number of elements between
938 /// `first` and `last`; otherwise, this operation has `O[N * log(N)]`
939 /// complexity. The (template parameter) type `INPUT_ITERATOR` shall
940 /// meet the requirements of an input iterator defined in the C++11
941 /// standard [input.iterators] providing access to values of a type
942 /// convertible to `value_type`, and `value_type` must be
943 /// `emplace-constructible` from `*i` into this map, where `i` is a
944 /// dereferenceable iterator in the range `[first .. last)` (see
945 /// {Requirements on `KEY` and `VALUE`}). The behavior is undefined
946 /// unless `first` and `last` refer to a sequence of valid values where
947 /// `first` is at a position at or before `last`.
948 template <class INPUT_ITERATOR>
949 map(INPUT_ITERATOR first,
950 INPUT_ITERATOR last,
951 const COMPARATOR& comparator = COMPARATOR(),
952 const ALLOCATOR& basicAllocator = ALLOCATOR());
953 template <class INPUT_ITERATOR>
954 map(INPUT_ITERATOR first,
955 INPUT_ITERATOR last,
956 const ALLOCATOR& basicAllocator);
957
958#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
959 map(std::initializer_list<value_type> values,
960 const COMPARATOR& comparator = COMPARATOR(),
961 const ALLOCATOR& basicAllocator = ALLOCATOR());
962 /// Create a map and insert each `value_type` object in the specified
963 /// `values` initializer list, ignoring those objects having a key
964 /// equivalent to that which appears earlier in the list. Optionally
965 /// specify a `comparator` used to order keys contained in this object.
966 /// If `comparator` is not supplied, a default-constructed object of the
967 /// (template parameter) type `COMPARATOR` is used. Optionally specify
968 /// a `basicAllocator` used to supply memory. If `basicAllocator` is
969 /// not supplied, a default-constructed object of the (template
970 /// parameter) type `ALLOCATOR` is used. If the type `ALLOCATOR` is
971 /// `bsl::allocator` (the default), then `basicAllocator`, if supplied,
972 /// shall be convertible to `bslma::Allocator *`. If the type
973 /// `ALLOCATOR` is `bsl::allocator` and `basicAllocator` is not
974 /// supplied, the currently installed default allocator is used. If
975 /// `values` is ordered according to `comparator`, then this operation
976 /// has `O[N]` complexity, where `N` is the number of elements in
977 /// `values`; otherwise, this operation has `O[N * log(N)]` complexity.
978 /// This method requires that the (template parameter) types `KEY` and
979 /// `VALUE` both be `copy-insertable` into this map (see {Requirements
980 /// on `KEY` and `VALUE`}).
981 map(std::initializer_list<value_type> values,
982 const ALLOCATOR& basicAllocator);
983#endif
984
985 /// Destroy this object.
987
988 // MANIPULATORS
989
990 /// Assign to this object the value and comparator of the specified
991 /// `rhs` object, propagate to this object the allocator of `rhs` if the
992 /// `ALLOCATOR` type has trait `propagate_on_container_copy_assignment`,
993 /// and return a reference providing modifiable access to this object.
994 /// If an exception is thrown, `*this` is left in a valid but
995 /// unspecified state. This method requires that the (template
996 /// parameter) types `KEY` and `VALUE` both be `copy-assignable` and
997 /// `copy-insertable` into this map (see {Requirements on `KEY` and
998 /// `VALUE`}).
999 map& operator=(const map& rhs);
1000
1001 map& operator=(BloombergLP::bslmf::MovableRef<map> rhs)
1003 AllocatorTraits::is_always_equal::value &&
1004 std::is_nothrow_move_assignable<COMPARATOR>::value);
1005 // Assign to this object the value and comparator of the specified
1006 // 'rhs' object, propagate to this object the allocator of 'rhs' if the
1007 // 'ALLOCATOR' type has trait 'propagate_on_container_move_assignment',
1008 // and return a reference providing modifiable access to this object.
1009 // The contents of 'rhs' are moved (in constant time) to this map if
1010 // 'get_allocator() == rhs.get_allocator()' (after accounting for the
1011 // aforementioned trait); otherwise, all elements in this map are
1012 // either destroyed or move-assigned to and each additional element in
1013 // 'rhs' is move-inserted into this map. 'rhs' is left in a valid but
1014 // unspecified state, and if an exception is thrown, '*this' is left
1015 // in a valid but unspecified state. This method requires that the
1016 // (template parameter) types 'KEY' and 'VALUE' both be
1017 // 'move-assignable' and 'move-insertable' into this map (see
1018 // {Requirements on 'KEY' and 'VALUE'}).
1019
1020#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1021 /// Assign to this object the value resulting from first clearing this
1022 /// map and then inserting each `value_type` object in the specified
1023 /// `values` initializer list, ignoring those objects having a key
1024 /// equivalent to that which appears earlier in the list; return a
1025 /// reference providing modifiable access to this object. This method
1026 /// requires that the (template parameter) types `KEY` and `VALUE` both
1027 /// be `copy-insertable` into this map (see {Requirements on `KEY` and
1028 /// `VALUE`}).
1029 map& operator=(std::initializer_list<value_type> values);
1030#endif
1031
1032 /// Return a reference providing modifiable access to the mapped-value
1033 /// associated with the specified `key`; if this `map` does not already
1034 /// contain a `value_type` object having an equivalent key, first insert
1035 /// a new `value_type` object having `key` and a default-constructed
1036 /// `VALUE` object, and return a reference to the newly mapped (default)
1037 /// value. This method requires that the (template parameter) type
1038 /// `KEY` be `copy-insertable` into this map and the (template
1039 /// parameter) type `VALUE` be `default-insertable` into this map (see
1040 /// {Requirements on `KEY` and `VALUE`}).
1042
1043 /// Return a reference providing modifiable access to the mapped-value
1044 /// associated with the specified `key`; if this `map` does not already
1045 /// contain a `value_type` object having an equivalent key, first insert
1046 /// a new `value_type` object having the move-inserted `key` and a
1047 /// default-constructed `VALUE` object, and return a reference to the
1048 /// newly mapped (default) value. This method requires that the
1049 /// (template parameter) type `KEY` be `move-insertable` into this map
1050 /// and the (template parameter) type `VALUE` be `default-insertable`
1051 /// into this map (see {Requirements on `KEY` and `VALUE`}).
1053 BloombergLP::bslmf::MovableRef<key_type> key);
1054
1055 /// Return a reference providing modifiable access to the mapped-value
1056 /// associated with the specified `key`, if such an entry exists;
1057 /// otherwise, throw a `std::out_of_range` exception. Note that this
1058 /// method may also throw a different kind of exception if the
1059 /// (user-supplied) comparator throws.
1061
1062 /// Return an iterator providing modifiable access to the first
1063 /// `value_type` object in the ordered sequence of `value_type` objects
1064 /// maintained by this map, or the `end` iterator if this map is empty.
1066
1067 /// Return an iterator providing modifiable access to the past-the-end
1068 /// element in the ordered sequence of `value_type` objects maintained
1069 /// by this map.
1071
1072 /// Return a reverse iterator providing modifiable access to the last
1073 /// `value_type` object in the ordered sequence of `value_type` objects
1074 /// maintained by this map, or `rend` if this map is empty.
1076
1077 /// Return a reverse iterator providing modifiable access to the
1078 /// prior-to-the-beginning element in the ordered sequence of
1079 /// `value_type` objects maintained by this map.
1081
1082 /// Insert the specified `value` into this map if a key (the `first`
1083 /// element) equivalent to that of `value` does not already exist in
1084 /// this map; otherwise, if a `value_type` object whose key is
1085 /// equivalent to that of `value` already exists in this map, this
1086 /// method has no effect. Return a pair whose `first` member is an
1087 /// iterator referring to the (possibly newly inserted) `value_type`
1088 /// object in this map whose key is equivalent to that of `value`, and
1089 /// whose `second` member is `true` if a new value was inserted, and
1090 /// `false` if the key was already present. This method requires that
1091 /// the (template parameter) types `KEY` and `VALUE` both be
1092 /// `copy-insertable` into this map (see {Requirements on `KEY` and
1093 /// `VALUE`}).
1094 pair<iterator, bool> insert(const value_type& value);
1095
1096 /// Insert into this map the specified `value` if a key (the `first`
1097 /// element) equivalent to that of `value` does not already exist in
1098 /// this map; otherwise, this method has no effect. Return a pair whose
1099 /// `first` member is an iterator referring to the (possibly newly
1100 /// inserted) `value_type` object in this map whose key is equivalent to
1101 /// that of `value`, and whose `second` member is `true` if a new value
1102 /// was inserted and `false` if the key was already present. This
1103 /// method requires that the (template parameter) types `KEY` and
1104 /// `VALUE` both be `move-insertable` into this map (see {Requirements
1105 /// on `KEY` and `VALUE`}).
1107 BloombergLP::bslmf::MovableRef<value_type> value);
1108
1109#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
1110 template <class ALT_VALUE_TYPE>
1112#elif !defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
1113 template <class ALT_VALUE_TYPE>
1115 pair<iterator, bool> >::type
1116#else
1117 /// Insert into this map a `value_type` object created from the
1118 /// specified `value` if a key (the `first` element) equivalent to that
1119 /// of such an object does not already exist in this map; otherwise,
1120 /// this method has no effect (other than possibly creating a temporary
1121 /// `value_type` object). Return a pair whose `first` member is an
1122 /// iterator referring to the (possibly newly inserted) `value_type`
1123 /// object in this map whose key is equivalent to that of the object
1124 /// created from `value`, and whose `second` member is `true` if a new
1125 /// value was inserted and `false` if the key was already present. This
1126 /// method requires that the (template parameter) types `KEY` and
1127 /// `VALUE` both be `move-insertable` into this map (see {Requirements
1128 /// on `KEY` and `VALUE`}), and the `value_type` be constructible from
1129 /// the (template parameter) `ALT_VALUE_TYPE`.
1130 template <class ALT_VALUE_TYPE>
1131 typename enable_if<std::is_constructible<value_type,
1132 ALT_VALUE_TYPE&&>::value,
1133 pair<iterator, bool> >::type
1134#endif
1136 {
1137 // This function has to be implemented inline, in violation of BDE
1138 // convention, as the MSVC compiler cannot match the out-of-class
1139 // definition of the declaration in the class.
1140
1141 return emplace(BSLS_COMPILERFEATURES_FORWARD(ALT_VALUE_TYPE, value));
1142 }
1143
1144 /// Insert the specified `value` into this map (in amortized constant
1145 /// time if the specified `hint` is a valid immediate successor to the
1146 /// key of `value`) if a key (the `first` element) equivalent to that of
1147 /// `value` does not already exist in this map; otherwise, if a
1148 /// `value_type` object whose key is equivalent to that of `value`
1149 /// already exists in this map, this method has no effect. Return an
1150 /// iterator referring to the (possibly newly inserted) `value_type`
1151 /// object in this map whose key is equivalent to that of `value`. If
1152 /// `hint` is not a valid immediate successor to the key of `value`,
1153 /// this operation has `O[log(N)]` complexity, where `N` is the size of
1154 /// this map. This method requires that the (template parameter) types
1155 /// `KEY` and `VALUE` both be `copy-insertable` into this map (see
1156 /// {Requirements on `KEY` and `VALUE`}). The behavior is undefined
1157 /// unless `hint` is an iterator in the range `[begin() .. end()]` (both
1158 /// endpoints included).
1160
1161 /// Insert into this map the specified `value` (in amortized constant
1162 /// time if the specified `hint` is a valid immediate successor to
1163 /// `value`) if a key (the `first` element) equivalent to that of
1164 /// `value` does not already exist in this map; otherwise, this method
1165 /// has no effect. Return an iterator referring to the (possibly newly
1166 /// inserted) `value_type` object in this map whose key is equivalent to
1167 /// that of `value`. If `hint` is not a valid immediate successor to
1168 /// `value`, this operation has `O[log(N)]` complexity, where `N` is the
1169 /// size of this map. This method requires that the (template
1170 /// parameter) types `KEY` and `VALUE` both be `move-insertable` into
1171 /// this map (see {Requirements on `KEY` and `VALUE`}). The behavior is
1172 /// undefined unless `hint` is an iterator in the range
1173 /// `[begin() .. end()]` (both endpoints included).
1175 BloombergLP::bslmf::MovableRef<value_type> value);
1176
1177#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
1178 template <class ALT_VALUE_TYPE>
1179 iterator
1180#elif !defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
1181 template <class ALT_VALUE_TYPE>
1183 iterator>::type
1184#else
1185 /// Insert into this map a `value_type` object created from the
1186 /// specified `value` (in amortized constant time if the specified
1187 /// `hint` is a valid immediate successor to the object created from
1188 /// `value`) if a key (the `first` element) equivalent to such an object
1189 /// does not already exist in this map; otherwise, this method has no
1190 /// effect (other than possibly creating a temporary `value_type`
1191 /// object). Return an iterator referring to the (possibly newly
1192 /// inserted) `value_type` object in this map whose key is equivalent to
1193 /// that of the object created from `value`. If `hint` is not a valid
1194 /// immediate successor to the object created from `value`, this
1195 /// operation has `O[log(N)]` complexity, where `N` is the size of this
1196 /// map. This method requires that the (template parameter) types `KEY`
1197 /// and `VALUE` both be `move-insertable` into this map (see
1198 /// {Requirements on `KEY` and `VALUE`}), and the `value_type` be
1199 /// constructible from the (template parameter) `ALT_VALUE_TYPE`. The
1200 /// behavior is undefined unless `hint` is an iterator in the range
1201 /// `[begin() .. end()]` (both endpoints included).
1202 template <class ALT_VALUE_TYPE>
1203 typename enable_if<std::is_constructible<value_type,
1204 ALT_VALUE_TYPE&&>::value,
1205 iterator>::type
1206#endif
1208 BSLS_COMPILERFEATURES_FORWARD_REF(ALT_VALUE_TYPE) value)
1209 {
1210 // This function has to be implemented inline, in violation of BDE
1211 // convention, as the MSVC compiler cannot match the out-of-class
1212 // definition of the declaration in the class.
1213
1214 return emplace_hint(
1215 hint,
1216 BSLS_COMPILERFEATURES_FORWARD(ALT_VALUE_TYPE, value));
1217 }
1218
1219 /// Insert into this map the value of each `value_type` object in the
1220 /// range starting at the specified `first` iterator and ending
1221 /// immediately before the specified `last` iterator, if a key
1222 /// equivalent to that of the object is not already contained in this
1223 /// map. The (template parameter) type `INPUT_ITERATOR` shall meet the
1224 /// requirements of an input iterator defined in the C++11 standard
1225 /// [input.iterators] providing access to values of a type convertible
1226 /// to `value_type`, and `value_type` must be `emplace-constructible`
1227 /// from `*i` into this map, where `i` is a dereferenceable iterator in
1228 /// the range `[first .. last)` (see {Requirements on `KEY` and
1229 /// `VALUE`}). The behavior is undefined unless `first` and `last`
1230 /// refer to a sequence of valid values where `first` is at a position
1231 /// at or before `last`.
1232 template <class INPUT_ITERATOR>
1233 void insert(INPUT_ITERATOR first, INPUT_ITERATOR last);
1234
1235#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
1236 void insert(const_iterator first, const_iterator last);
1237 // This method is provided only on Sun to work around a bug in the Sun
1238 // Studio 12.3 compiler, which prevents us from disabling (at compile
1239 // time) the overload of 'insert' taking a 'const_iterator' and a
1240 // forwarding reference if the second argument is not convertible to
1241 // the value type associated with the map. Without such a check, in
1242 // certain cases, the same compiler complains of ambiguity between
1243 // the 'insert' method taking two input iterators and the 'insert'
1244 // method taking a 'const_iterator' and a forwarding reference; such
1245 // an ambiguity is resolved by providing this method, which is
1246 // equivalent to the 'insert' method (above) taking two input iterators
1247 // of template parameter type.
1248#endif
1249
1250#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1251 /// Insert into this map the value of each `value_type` object in the
1252 /// specified `values` initializer list if a key equivalent to that of
1253 /// the object is not already contained in this map. This method
1254 /// requires that the (template parameter) types `KEY` and `VALUE` both
1255 /// be `copy-insertable` into this map (see {Requirements on `KEY` and
1256 /// `VALUE`}).
1257 void insert(std::initializer_list<value_type> values);
1258#endif
1259
1260#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1261 /// If a key equivalent to the specified `key` already exists in this
1262 /// map, assign the specified `obj` to the value associated with that
1263 /// key, and return a pair containing an iterator referring to the
1264 /// existing item and `false`. Otherwise, insert into this map a
1265 /// newly-created `value_type` object, constructed from
1266 /// `(key, std::forward<BDE_OTHER_TYPE>(obj)...))`, and return a pair
1267 /// containing an iterator referring to the newly-created entry and
1268 /// `true`.
1269 template <class BDE_OTHER_TYPE>
1271 BDE_OTHER_TYPE&& obj);
1272
1273 /// If a key equivalent to the specified `key` already exists in this
1274 /// map, assign the specified `obj` to the value associated with that
1275 /// key, and return a pair containing an iterator referring to the
1276 /// existing item and `false`. Otherwise, insert into this map a
1277 /// newly-created `value_type` object, constructed from
1278 /// `(std::forward<KEY>(key), std::forward<BDE_OTHER_TYPE>(obj)...))`,
1279 /// and return a pair containing an iterator referring to the
1280 /// newly-created entry and `true`.
1281 template <class BDE_OTHER_TYPE>
1283 BloombergLP::bslmf::MovableRef<KEY> key,
1284 BDE_OTHER_TYPE&& obj);
1285
1286 /// If a key equivalent to the specified `key` already exists in this
1287 /// map, assign the specified `obj` to the value associated with that
1288 /// key, and return an iterator referring to the existing item.
1289 /// Otherwise, insert into this map a newly-created `value_type` object,
1290 /// constructed from `(key, std::forward<BDE_OTHER_TYPE>(obj)...))`, and
1291 /// return an iterator referring to the newly-created entry. Use the
1292 /// specified `hint` as a starting point for checking to see if the key
1293 /// is already in the map.
1294 template <class BDE_OTHER_TYPE>
1296 const KEY& key,
1297 BDE_OTHER_TYPE&& obj);
1298
1299 /// If a key equivalent to the specified `key` already exists in this
1300 /// _map, assign the specified `obj` to the value associated with that
1301 /// key, and return an iterator referring to the existing item.
1302 /// Otherwise, insert into this map a newly-created `value_type` object
1303 /// constructed from
1304 /// `(std::forward<KEY>(key), std::forward<BDE_OTHER_TYPE>(obj)...))`,
1305 /// and return an iterator referring to the newly-created entry. Use
1306 /// the specified `hint` as a starting point for checking to see if the
1307 /// key already in the map.
1308 template <class BDE_OTHER_TYPE>
1310 BloombergLP::bslmf::MovableRef<KEY> key,
1311 BDE_OTHER_TYPE&& obj);
1312#endif
1313
1314#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1315 /// Insert into this map a newly-created `value_type` object,
1316 /// constructed by forwarding `get_allocator()` (if required) and the
1317 /// specified (variable number of) `args` to the corresponding
1318 /// constructor of `value_type`, if a key equivalent to such a value
1319 /// does not already exist in this map; otherwise, this method has no
1320 /// effect (other than possibly creating a temporary `value_type`
1321 /// object). Return a pair whose `first` member is an iterator
1322 /// referring to the (possibly newly created and inserted) object in
1323 /// this map whose key is equivalent to that of an object constructed
1324 /// from `args`, and whose `second` member is `true` if a new value was
1325 /// inserted, and `false` if an equivalent key was already present.
1326 /// This method requires that the (template parameter) types `KEY` and
1327 /// `VALUE` both be `emplace-constructible` from `args` (see
1328 /// {Requirements on `KEY` and `VALUE`}).
1329 template <class... Args>
1331
1332 /// Insert into this map a newly-created `value_type` object,
1333 /// constructed by forwarding `get_allocator()` (if required) and the
1334 /// specified (variable number of) `args` to the corresponding
1335 /// constructor of `value_type` (in amortized constant time if the
1336 /// specified `hint` is a valid immediate successor to the `value_type`
1337 /// object constructed from `args`), if a key equivalent to such a value
1338 /// does not already exist in this map; otherwise, this method has no
1339 /// effect (other than possibly creating a temporary `value_type`
1340 /// object). Return an iterator referring to the (possibly newly
1341 /// created and inserted) object in this map whose key is equivalent to
1342 /// that of an object constructed from `args`. If `hint` is not a valid
1343 /// immediate successor to the `value_type` object implied by `args`,
1344 /// this operation has `O[log(N)]` complexity where `N` is the size of
1345 /// this map. This method requires that the (template parameter) types
1346 /// `KEY` and `VALUE` both be `emplace-constructible` from `args` (see
1347 /// {Requirements on `KEY` and `VALUE`}). The behavior is undefined
1348 /// unless `hint` is an iterator in the range `[begin() .. end()]` (both
1349 /// endpoints included).
1350 template <class... Args>
1351 iterator emplace_hint(const_iterator hint, Args&&... args);
1352#endif
1353
1355 /// Remove from this map the `value_type` object at the specified
1356 /// `position`, and return an iterator referring to the element
1357 /// immediately following the removed element, or to the past-the-end
1358 /// position if the removed element was the last element in the sequence
1359 /// of elements maintained by this map. This method invalidates only
1360 /// iterators and references to the removed element and previously saved
1361 /// values of the `end()` iterator. The behavior is undefined unless
1362 /// `position` refers to a `value_type` object in this map.
1364
1365 /// Remove from this map the `value_type` object whose key is equivalent
1366 /// the specified `key`, if such an entry exists, and return 1;
1367 /// otherwise, if there is no `value_type` object having an equivalent
1368 /// key, return 0 with no other effect. This method invalidates only
1369 /// iterators and references to the removed element and previously saved
1370 /// values of the `end()` iterator.
1372
1374 /// Remove from this map the `value_type` objects starting at the
1375 /// specified `first` position up to, but including the specified `last`
1376 /// position, and return `last`. This method invalidates only
1377 /// iterators and references to the removed element and previously saved
1378 /// values of the `end()` iterator. The behavior is undefined unless
1379 /// `first` and `last` either refer to elements in this map or are the
1380 /// `end` iterator, and the `first` position is at or before the `last`
1381 /// position in the ordered sequence provided by this container.
1382
1383 void swap(map& other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(
1384 AllocatorTraits::is_always_equal::value &&
1385 bsl::is_nothrow_swappable<COMPARATOR>::value);
1386 // Exchange the value and comparator of this object with those of the
1387 // specified 'other' object; also exchange the allocator of this object
1388 // with that of 'other' if the (template parameter) type 'ALLOCATOR'
1389 // has the 'propagate_on_container_swap' trait, and do not modify
1390 // either allocator otherwise. This method provides the no-throw
1391 // exception-safety guarantee if and only if the (template parameter)
1392 // type 'COMPARATOR' provides a no-throw swap operation, and provides
1393 // the basic exception-safety guarantee otherwise; if an exception is
1394 // thrown, both objects are left in valid but unspecified states. This
1395 // operation has 'O[1]' complexity if either this object was created
1396 // with the same allocator as 'other' or 'ALLOCATOR' has the
1397 // 'propagate_on_container_swap' trait; otherwise, it has 'O[n + m]'
1398 // complexity, where 'n' and 'm' are the number of elements in this
1399 // object and 'other', respectively. Note that this method's support
1400 // for swapping objects created with different allocators when
1401 // 'ALLOCATOR' does not have the 'propagate_on_container_swap' trait is
1402 // a departure from the C++ Standard.
1403
1404#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1405 /// If a key equivalent to the specified `key` already exists in this
1406 /// map, return a pair containing an iterator referring to the existing
1407 /// item and `false`. Otherwise, insert into this map a newly-created
1408 /// entry constructed from `key` and the specified `args`, and return a
1409 /// pair containing an iterator referring to the newly-created entry and
1410 /// `true`. This method requires that the (template parameter) types
1411 /// `KEY` and `VALUE` are `emplace-constructible` from `key` and `args`
1412 /// respectively. For C++03, `VALUE` must also be `copy-constructible`.
1413 ///
1414 /// Note: implemented inline due to Sun CC compilation error.
1415 template <class... Args>
1416 pair<iterator, bool> try_emplace(const KEY& key, Args&&... args);
1417 template <class... Args>
1418 pair<iterator, bool> try_emplace(BloombergLP::bslmf::MovableRef<KEY> key,
1419 Args&&... args);
1420 template<class LOOKUP_KEY, class... Args>
1421 typename bsl::enable_if<
1422 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1423 LOOKUP_KEY>::value &&
1426 pair<iterator, bool> >::type
1427 try_emplace(LOOKUP_KEY&& key, Args&&... args)
1428 {
1429 const LOOKUP_KEY& lvalue = key;
1430
1431 int comparisonResult;
1432 BloombergLP::bslalg::RbTreeNode *insertLocation =
1433 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
1434 &comparisonResult,
1435 &d_tree,
1436 this->comparator(),
1437 lvalue);
1438 if (!comparisonResult) {
1439 return pair<iterator, bool>(
1440 iterator(insertLocation), false); // RETURN
1441 }
1442
1443 #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
1444 BloombergLP::bslalg::RbTreeNode *node =
1445 nodeFactory().emplaceIntoNewNode(
1446 std::piecewise_construct,
1447 std::forward_as_tuple(std::forward<LOOKUP_KEY>(key)),
1448 std::forward_as_tuple(std::forward<Args>(args)...));
1449 #else
1450 BloombergLP::bslalg::RbTreeNode *node =
1451 nodeFactory().emplaceIntoNewNode(
1452 std::forward<LOOKUP_KEY>(key),
1453 mapped_type(std::forward<Args>(args)...));
1454 #endif
1455
1456 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
1457 insertLocation,
1458 comparisonResult < 0,
1459 node);
1460
1461 return pair<iterator, bool>(iterator(node), true);
1462 }
1463
1464 /// If a key equivalent to the specified `key` already exists in this
1465 /// map, return an iterator referring to the existing item. Otherwise,
1466 /// insert into this map a newly-created `value_type` object,
1467 /// constructed from from `key` and the specified `args`, and return an
1468 /// iterator referring to the newly-created entry. Use the specified
1469 /// `hint` as a starting point for checking to see if the key already in
1470 /// the map. This method requires that the (template parameter) types
1471 /// `KEY` and `VALUE` are `emplace-constructible` from `key` and `args`
1472 /// respectively. For C++03, `VALUE` must also be `copy-constructible`.
1473 ///
1474 /// Note: implemented inline due to Sun CC compilation error.
1475 template<class... Args>
1476 iterator try_emplace(const_iterator hint, const KEY& key, Args&&... args);
1477 template <class... Args>
1479 BloombergLP::bslmf::MovableRef<KEY> key,
1480 Args&&... args);
1481 template<class LOOKUP_KEY, class... Args>
1482 typename bsl::enable_if<
1483 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1484 LOOKUP_KEY>::value,
1485 iterator>::type
1486 try_emplace(const_iterator hint, LOOKUP_KEY&& key, Args&&... args)
1487 {
1488 const LOOKUP_KEY& lvalue = key;
1489
1490 BloombergLP::bslalg::RbTreeNode *hintNode =
1491 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
1492
1493 int comparisonResult;
1494 BloombergLP::bslalg::RbTreeNode *insertLocation =
1495 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
1496 &comparisonResult,
1497 &d_tree,
1498 this->comparator(),
1499 lvalue,
1500 hintNode);
1501
1502 if (!comparisonResult) {
1503 return iterator(insertLocation); // RETURN
1504 }
1505
1506 #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
1507 BloombergLP::bslalg::RbTreeNode *node =
1508 nodeFactory().emplaceIntoNewNode(
1509 std::piecewise_construct,
1510 std::forward_as_tuple(std::forward<LOOKUP_KEY>(key)),
1511 std::forward_as_tuple(std::forward<Args>(args)...));
1512 #else
1513 BloombergLP::bslalg::RbTreeNode *node =
1514 nodeFactory().emplaceIntoNewNode(
1515 std::forward<LOOKUP_KEY>(key),
1516 mapped_type(std::forward<Args>(args)...));
1517 #endif
1518
1519 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
1520 insertLocation,
1521 comparisonResult < 0,
1522 node);
1523
1524 return iterator(node);
1525 }
1526#endif
1527
1528 /// Remove all entries from this map. Note that the map is empty after
1529 /// this call, but allocated memory may be retained for future use.
1531
1532 // Turn off complaints about necessarily class-defined methods.
1533 // BDE_VERIFY pragma: push
1534 // BDE_VERIFY pragma: -CD01
1535
1536 /// Return an iterator providing modifiable access to the `value_type`
1537 /// object in this map whose key is equivalent to the specified `key`,
1538 /// if such an entry exists, and the past-the-end (`end`) iterator
1539 /// otherwise.
1540 ///
1541 /// Note: implemented inline due to Sun CC compilation error.
1542 iterator find(const key_type& key)
1543 {
1544 return iterator(BloombergLP::bslalg::RbTreeUtil::find(
1545 d_tree, this->comparator(), key));
1546 }
1547
1548 /// Return an iterator providing modifiable access to the `value_type`
1549 /// object in this map whose key is equivalent to the specified `key`,
1550 /// if such an entry exists, and the past-the-end (`end`) iterator
1551 /// otherwise.
1552 ///
1553 /// Note: implemented inline due to Sun CC compilation error.
1554 template <class LOOKUP_KEY>
1555 typename bsl::enable_if<
1556 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1557 LOOKUP_KEY>::value,
1558 iterator>::type
1559 find(const LOOKUP_KEY& key)
1560 {
1561 return iterator(BloombergLP::bslalg::RbTreeUtil::find(
1562 d_tree, this->comparator(), key));
1563 }
1564
1565 /// Return an iterator providing modifiable access to the first (i.e.,
1566 /// ordered least) `value_type` object in this map whose key is
1567 /// greater-than or equal-to the specified `key`, and the past-the-end
1568 /// iterator if this map does not contain a `value_type` object whose
1569 /// key is greater-than or equal-to `key`. Note that this function
1570 /// returns the *first* position before which a `value_type` object
1571 /// having an equivalent key could be inserted into the ordered sequence
1572 /// maintained by this map, while preserving its ordering.
1573 ///
1574 /// Note: implemented inline due to Sun CC compilation error.
1576 {
1577 return iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1578 d_tree, this->comparator(), key));
1579 }
1580
1581 /// Return an iterator providing modifiable access to the first (i.e.,
1582 /// ordered least) `value_type` object in this map whose key is
1583 /// greater-than or equal-to the specified `key`, and the past-the-end
1584 /// iterator if this map does not contain a `value_type` object whose
1585 /// key is greater-than or equal-to `key`. Note that this function
1586 /// returns the *first* position before which a `value_type` object
1587 /// having an equivalent key could be inserted into the ordered sequence
1588 /// maintained by this map, while preserving its ordering.
1589 ///
1590 /// Note: implemented inline due to Sun CC compilation error.
1591 template <class LOOKUP_KEY>
1592 typename bsl::enable_if<
1593 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1594 LOOKUP_KEY>::value,
1595 iterator>::type
1596 lower_bound(const LOOKUP_KEY& key)
1597 {
1598 return iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1599 d_tree, this->comparator(), key));
1600 }
1601
1602 /// Return an iterator providing modifiable access to the first (i.e.,
1603 /// ordered least) `value_type` object in this map whose key is greater
1604 /// than the specified `key`, and the past-the-end iterator if this map
1605 /// does not contain a `value_type` object whose key is greater-than
1606 /// `key`. Note that this function returns the *last* position before
1607 /// which a `value_type` object having an equivalent key could be
1608 /// inserted into the ordered sequence maintained by this map, while
1609 /// preserving its ordering.
1610 ///
1611 /// Note: implemented inline due to Sun CC compilation error.
1613 {
1614 return iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1615 d_tree, this->comparator(), key));
1616 }
1617
1618 /// Return an iterator providing modifiable access to the first (i.e.,
1619 /// ordered least) `value_type` object in this map whose key is greater
1620 /// than the specified `key`, and the past-the-end iterator if this map
1621 /// does not contain a `value_type` object whose key is greater-than
1622 /// `key`. Note that this function returns the *last* position before
1623 /// which a `value_type` object having an equivalent key could be
1624 /// inserted into the ordered sequence maintained by this map, while
1625 /// preserving its ordering.
1626 ///
1627 /// Note: implemented inline due to Sun CC compilation error.
1628 template <class LOOKUP_KEY>
1629 typename bsl::enable_if<
1630 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1631 LOOKUP_KEY>::value,
1632 iterator>::type
1633 upper_bound(const LOOKUP_KEY& key)
1634 {
1635 return iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1636 d_tree, this->comparator(), key));
1637 }
1638
1639 /// Return a pair of iterators providing modifiable access to the
1640 /// sequence of `value_type` objects in this map whose keys are
1641 /// equivalent to the specified `key`, where the first iterator is
1642 /// positioned at the start of the sequence and the second is positioned
1643 /// one past the end of the sequence. The first returned iterator will
1644 /// be `lower_bound(key)`, the second returned iterator will be
1645 /// `upper_bound(key)`, and, if this map contains no `value_type`
1646 /// objects with an equivalent key, then the two returned iterators will
1647 /// have the same value. Note that since a map maintains unique keys,
1648 /// the range will contain at most one element.
1649 ///
1650 /// Note: implemented inline due to Sun CC compilation error.
1652 {
1653 iterator startIt = lower_bound(key);
1654 iterator endIt = startIt;
1655 if (endIt != end() && !comparator()(key, *endIt.node())) {
1656 ++endIt;
1657 }
1658 return pair<iterator, iterator>(startIt, endIt);
1659 }
1660
1661 /// Return a pair of iterators providing modifiable access to the
1662 /// sequence of `value_type` objects in this map whose keys are
1663 /// equivalent to the specified `key`, where the first iterator is
1664 /// positioned at the start of the sequence and the second is positioned
1665 /// one past the end of the sequence. The first returned iterator will
1666 /// be `lower_bound(key)`, the second returned iterator will be
1667 /// `upper_bound(key)`, and, if this map contains no `value_type`
1668 /// objects with an equivalent key, then the two returned iterators will
1669 /// have the same value. Note that although a map maintains unique
1670 /// keys, the range may contain more than one element, because a
1671 /// transparent comparator may have been supplied that provides a
1672 /// different (but compatible) partitioning of keys for `LOOKUP_KEY` as
1673 /// the comparisons used to order the keys in the map.
1674 ///
1675 /// Note: implemented inline due to Sun CC compilation error.
1676 template <class LOOKUP_KEY>
1677 typename bsl::enable_if<
1678 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1679 LOOKUP_KEY>::value,
1681 equal_range(const LOOKUP_KEY& key)
1682 {
1683 iterator startIt = lower_bound(key);
1684 iterator endIt = startIt;
1685 if (endIt != end() && !comparator()(key, *endIt.node())) {
1686 ++endIt;
1687
1688 // Typically, even with a transparent comparator, we expect to find
1689 // either 0 or 1 matching keys. We test for those two common cases
1690 // before performing a logarithmic search via @ref upper_bound to
1691 // determine the end of the range.
1692
1693 if (endIt != end() && !comparator()(key, *endIt.node())) {
1694 endIt = upper_bound(key);
1695 }
1696 }
1697 return pair<iterator, iterator>(startIt, endIt);
1698 }
1699
1700 // BDE_VERIFY pragma: pop
1701
1702 // ACCESSORS
1703
1704 /// Return (a copy of) the allocator used for memory allocation by this
1705 /// map.
1707
1708 /// Return an iterator providing non-modifiable access to the first
1709 /// `value_type` object in the ordered sequence of `value_type` objects
1710 /// maintained by this map, or the `end` iterator if this map is empty.
1712
1713 /// Return an iterator providing non-modifiable access to the
1714 /// past-the-end element in the ordered sequence of `value_type`
1715 /// objects maintained by this map.
1717
1718 /// Return a reverse iterator providing non-modifiable access to the
1719 /// last `value_type` object in the ordered sequence of `value_type`
1720 /// objects maintained by this map, or `rend` if this map is empty.
1722
1723 /// Return a reverse iterator providing non-modifiable access to the
1724 /// prior-to-the-beginning element in the ordered sequence of
1725 /// `value_type` objects maintained by this map.
1727
1728 /// Return an iterator providing non-modifiable access to the first
1729 /// `value_type` object in the ordered sequence of `value_type` objects
1730 /// maintained by this map, or the `cend` iterator if this map is empty.
1732
1733 /// Return an iterator providing non-modifiable access to the
1734 /// past-the-end element in the ordered sequence of `value_type` objects
1735 /// maintained by this map.
1737
1738 /// Return a reverse iterator providing non-modifiable access to the
1739 /// last `value_type` object in the ordered sequence of `value_type`
1740 /// objects maintained by this map, or `crend` if this map is empty.
1742
1743 /// Return a reverse iterator providing non-modifiable access to the
1744 /// prior-to-the-beginning element in the ordered sequence of
1745 /// `value_type` objects maintained by this map.
1747
1748 /// Return `true` if this map contains an element whose key is
1749 /// equivalent to the specified `key`.
1750 bool contains(const key_type &key) const;
1751
1752 /// Return `true` if this map contains an element whose key is
1753 /// equivalent to the specified `key`.
1754 ///
1755 /// Note: implemented inline due to Sun CC compilation error
1756 template <class LOOKUP_KEY>
1757 typename bsl::enable_if<
1758 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1759 LOOKUP_KEY>::value,
1760 bool>::type
1761 contains(const LOOKUP_KEY& key) const
1762 {
1763 return find(key) != end();
1764 }
1765
1766 /// Return `true` if this map contains no elements, and `false`
1767 /// otherwise.
1769
1770 /// Return the number of elements in this map.
1772
1773 /// Return a theoretical upper bound on the largest number of elements
1774 /// that this map could possibly hold. Note that there is no guarantee
1775 /// that the map can successfully grow to the returned size, or even
1776 /// close to that size without running out of resources.
1778
1779 /// Return a reference providing non-modifiable access to the
1780 /// mapped-value associated with a key that is equivalent to the
1781 /// specified `key`, if such an entry exists; otherwise, throw a
1782 /// `std::out_of_range` exception. Note that this method may also throw
1783 /// a different kind of exception if the (user-supplied) comparator
1784 /// throws.
1785 typename add_lvalue_reference<const VALUE>::type at(const key_type& key)
1786 const;
1787
1788 /// Return the key-comparison functor (or function pointer) used by this
1789 /// map; if a comparator was supplied at construction, return its value;
1790 /// otherwise, return a default constructed @ref key_compare object. Note
1791 /// that this comparator compares objects of type `KEY`, which is the
1792 /// key part of the `value_type` objects contained in this map.
1794
1795 /// Return a functor for comparing two `value_type` objects by comparing
1796 /// their respective keys using `key_comp()`. Note that this
1797 /// comparator compares objects of type `value_type` (i.e.,
1798 /// `bsl::pair<const KEY, VALUE>`).
1799 value_compare value_comp() const;
1800
1801 // Turn off complaints about necessarily class-defined methods.
1802 // BDE_VERIFY pragma: push
1803 // BDE_VERIFY pragma: -CD01
1804
1805 /// Return an iterator providing non-modifiable access to the
1806 /// `value_type` object in this map whose key is equivalent to the
1807 /// specified `key`, if such an entry exists, and the past-the-end
1808 /// (`end`) iterator otherwise.
1809 ///
1810 /// Note: implemented inline due to Sun CC compilation error.
1811 const_iterator find(const key_type& key) const
1812 {
1813 return const_iterator(BloombergLP::bslalg::RbTreeUtil::find(
1814 d_tree, this->comparator(), key));
1815 }
1816
1817 /// Return an iterator providing non-modifiable access to the
1818 /// `value_type` object in this map whose key is equivalent to the
1819 /// specified `key`, if such an entry exists, and the past-the-end
1820 /// (`end`) iterator otherwise.
1821 ///
1822 /// Note: implemented inline due to Sun CC compilation error.
1823 template <class LOOKUP_KEY>
1824 typename bsl::enable_if<
1825 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1826 LOOKUP_KEY>::value,
1827 const_iterator>::type
1828 find(const LOOKUP_KEY& key) const
1829 {
1830 return const_iterator(BloombergLP::bslalg::RbTreeUtil::find(
1831 d_tree, this->comparator(), key));
1832 }
1833
1834 /// Return the number of `value_type` objects within this map whose keys
1835 /// are equivalent to the specified `key`. Note that since a map
1836 /// maintains unique keys, the returned value will be either 0 or 1.
1837 ///
1838 /// Note: implemented inline due to Sun CC compilation error.
1839 size_type count(const key_type& key) const
1840 {
1841 return (find(key) != end()) ? 1 : 0;
1842 }
1843
1844 /// Return the number of `value_type` objects within this map whose keys
1845 /// are equivalent to the specified `key`. Note that although a map
1846 /// maintains unique keys, the returned value can be other than 0 or 1,
1847 /// because a transparent comparator may have been supplied that
1848 /// provides a different (but compatible) partitioning of keys for
1849 /// `LOOKUP_KEY` as the comparisons used to order the keys in the map.
1850 ///
1851 /// Note: implemented inline due to Sun CC compilation error.
1852 template <class LOOKUP_KEY>
1853 typename bsl::enable_if<
1854 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1855 LOOKUP_KEY>::value,
1856 size_type>::type
1857 count(const LOOKUP_KEY& key) const
1858 {
1859 int count = 0;
1860 const_iterator it = lower_bound(key);
1861
1862 while (it != end() && !comparator()(key, *it.node())) {
1863 ++it;
1864 ++count;
1865 }
1866 return count;
1867 }
1868
1869 /// Return an iterator providing non-modifiable access to the first
1870 /// (i.e., ordered least) `value_type` object in this map whose key is
1871 /// greater-than or equal-to the specified `key`, and the past-the-end
1872 /// iterator if this map does not contain a `value_type` object whose
1873 /// key is greater-than or equal-to `key`. Note that this function
1874 /// returns the *first* position before which a `value_type` object
1875 /// having an equivalent key could be inserted into the ordered sequence
1876 /// maintained by this map, while preserving its ordering.
1877 ///
1878 /// Note: implemented inline due to Sun CC compilation error.
1880 {
1881 return iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1882 d_tree, this->comparator(), key));
1883 }
1884
1885 /// Return an iterator providing non-modifiable access to the first
1886 /// (i.e., ordered least) `value_type` object in this map whose key is
1887 /// greater-than or equal-to the specified `key`, and the past-the-end
1888 /// iterator if this map does not contain a `value_type` object whose
1889 /// key is greater-than or equal-to `key`. Note that this function
1890 /// returns the *first* position before which a `value_type` object
1891 /// having an equivalent key could be inserted into the ordered sequence
1892 /// maintained by this map, while preserving its ordering.
1893 ///
1894 /// Note: implemented inline due to Sun CC compilation error.
1895 template <class LOOKUP_KEY>
1896 typename bsl::enable_if<
1897 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1898 LOOKUP_KEY>::value,
1899 const_iterator>::type
1900 lower_bound(const LOOKUP_KEY& key) const
1901 {
1902 return const_iterator(
1903 BloombergLP::bslalg::RbTreeUtil::lowerBound(d_tree,
1904 this->comparator(),
1905 key));
1906 }
1907
1908 /// Return an iterator providing non-modifiable access to the first
1909 /// (i.e., ordered least) `value_type` object in this map whose key is
1910 /// greater than the specified `key`, and the past-the-end iterator if
1911 /// this map does not contain a `value_type` object whose key is
1912 /// greater-than `key`. Note that this function returns the *last*
1913 /// position before which a `value_type` object having an equivalent key
1914 /// could be inserted into the ordered sequence maintained by this map,
1915 /// while preserving its ordering.
1916 ///
1917 /// Note: implemented inline due to Sun CC compilation error.
1919 {
1920 return const_iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1921 d_tree, this->comparator(), key));
1922 }
1923
1924 /// Return an iterator providing non-modifiable access to the first
1925 /// (i.e., ordered least) `value_type` object in this map whose key is
1926 /// greater than the specified `key`, and the past-the-end iterator if
1927 /// this map does not contain a `value_type` object whose key is
1928 /// greater-than `key`. Note that this function returns the *last*
1929 /// position before which a `value_type` object having an equivalent key
1930 /// could be inserted into the ordered sequence maintained by this map,
1931 /// while preserving its ordering.
1932 ///
1933 /// Note: implemented inline due to Sun CC compilation error.
1934 template <class LOOKUP_KEY>
1935 typename bsl::enable_if<
1936 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1937 LOOKUP_KEY>::value,
1938 const_iterator>::type
1939 upper_bound(const LOOKUP_KEY& key) const
1940 {
1941 return const_iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1942 d_tree, this->comparator(), key));
1943 }
1944
1945 /// Return a pair of iterators providing non-modifiable access to the
1946 /// sequence of `value_type` objects in this map whose keys are
1947 /// equivalent to the specified `key`, where the first iterator is
1948 /// positioned at the start of the sequence and the second iterator is
1949 /// positioned one past the end of the sequence. The first returned
1950 /// iterator will be `lower_bound(key)`, the second returned iterator
1951 /// will be `upper_bound(key)`, and, if this map contains no
1952 /// `value_type` objects having keys equivalent to `key`, then the two
1953 /// returned iterators will have the same value. Note that since a map
1954 /// maintains unique keys, the range will contain at most one element.
1955 ///
1956 /// Note: implemented inline due to Sun CC compilation error.
1958 {
1959 const_iterator startIt = lower_bound(key);
1960 const_iterator endIt = startIt;
1961 if (endIt != end() && !comparator()(key, *endIt.node())) {
1962 ++endIt;
1963 }
1964 return pair<const_iterator, const_iterator>(startIt, endIt);
1965 }
1966
1967 /// Return a pair of iterators providing non-modifiable access to the
1968 /// sequence of `value_type` objects in this map whose keys are
1969 /// equivalent to the specified `key`, where the first iterator is
1970 /// positioned at the start of the sequence and the second iterator is
1971 /// positioned one past the end of the sequence. The first returned
1972 /// iterator will be `lower_bound(key)`, the second returned iterator
1973 /// will be `upper_bound(key)`, and, if this map contains no
1974 /// `value_type` objects having keys equivalent to `key`, then the two
1975 /// returned iterators will have the same value. Note that although a
1976 /// map maintains unique keys, the range may contain more than one
1977 /// element, because a transparent comparator may have been supplied
1978 /// that provides a different (but compatible) partitioning of keys for
1979 /// `LOOKUP_KEY` as the comparisons used to order the keys in the map.
1980 ///
1981 /// Note: implemented inline due to Sun CC compilation error.
1982 template <class LOOKUP_KEY>
1983 typename bsl::enable_if<
1984 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1985 LOOKUP_KEY>::value,
1987 equal_range(const LOOKUP_KEY& key) const
1988 {
1989 const_iterator startIt = lower_bound(key);
1990 const_iterator endIt = startIt;
1991 if (endIt != end() && !comparator()(key, *endIt.node())) {
1992 ++endIt;
1993
1994 // Typically, even with a transparent comparator, we expect to find
1995 // either 0 or 1 matching keys. We test for those two common cases
1996 // before performing a logarithmic search via @ref upper_bound to
1997 // determine the end of the range.
1998
1999 if (endIt != end() && !comparator()(key, *endIt.node())) {
2000 endIt = upper_bound(key);
2001 }
2002 }
2003 return pair<const_iterator, const_iterator>(startIt, endIt);
2004 }
2005
2006 // BDE_VERIFY pragma: pop
2007};
2008
2009#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
2010// CLASS TEMPLATE DEDUCTION GUIDES
2011
2012/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
2013/// of the iterators supplied to the constructor of `map`. Deduce the
2014/// template parameters `COMPARATOR` and `ALLOCATOR` from the other
2015/// parameters passed to the constructor. This deduction guide does not
2016/// participate unless the supplied allocator meets the requirements of a
2017/// standard allocator.
2018template <
2019 class INPUT_ITERATOR,
2020 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
2021 class VALUE =
2022 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
2023 class COMPARATOR = std::less<KEY>,
2024 class ALLOCATOR = bsl::allocator<
2025 BloombergLP::bslstl::IteratorUtil::IterToAlloc_t<INPUT_ITERATOR>>,
2026 class = bsl::enable_if_t<!bsl::IsStdAllocator_v<COMPARATOR>>,
2027 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
2028 >
2029map(INPUT_ITERATOR,
2030 INPUT_ITERATOR,
2031 COMPARATOR = COMPARATOR(),
2032 ALLOCATOR = ALLOCATOR())
2033-> map<KEY, VALUE, COMPARATOR, ALLOCATOR>;
2034
2035/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
2036/// of the iterators supplied to the constructor of `map`. Deduce the
2037/// template parameter `COMPARATOR` from the other parameter passed to the
2038/// constructor. This deduction guide does not participate unless the
2039/// supplied allocator is convertible to
2040/// `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
2041template <
2042 class INPUT_ITERATOR,
2043 class COMPARATOR,
2044 class ALLOC,
2045 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
2046 class VALUE =
2047 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
2048 class DEFAULT_ALLOCATOR = bsl::allocator<pair<const KEY, VALUE>>,
2049 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
2050 >
2051map(INPUT_ITERATOR, INPUT_ITERATOR, COMPARATOR, ALLOC *)
2052-> map<KEY, VALUE, COMPARATOR>;
2053
2054/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
2055/// of the iterators supplied to the constructor of `map`. This deduction
2056/// guide does not participate unless the supplied allocator meets the
2057/// requirements of a standard allocator.
2058template <
2059 class INPUT_ITERATOR,
2060 class ALLOCATOR,
2061 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
2062 class VALUE =
2063 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
2064 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
2065 >
2066map(INPUT_ITERATOR, INPUT_ITERATOR, ALLOCATOR)
2067-> map<KEY, VALUE, std::less<KEY>, ALLOCATOR>;
2068
2069/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
2070/// of the iterators supplied to the constructor of `map`. This deduction
2071/// guide does not participate unless the supplied allocator is convertible
2072/// to `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
2073template <
2074 class INPUT_ITERATOR,
2075 class ALLOC,
2076 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
2077 class VALUE =
2078 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
2079 class DEFAULT_ALLOCATOR = bsl::allocator<pair<const KEY, VALUE>>,
2080 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
2081 >
2082map(INPUT_ITERATOR, INPUT_ITERATOR, ALLOC *)
2083-> map<KEY, VALUE>;
2084
2085/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
2086/// of the initializer_list supplied to the constructor of `map`. Deduce
2087/// the template parameters `COMPARATOR` and `ALLOCATOR` from the other
2088/// parameters passed to the constructor. This deduction guide does not
2089/// participate unless the supplied allocator meets the requirements of a
2090/// standard allocator.
2091template <
2092 class KEY,
2093 class VALUE,
2094 class COMPARATOR = std::less<KEY>,
2095 class ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
2096 class = bsl::enable_if_t<!bsl::IsStdAllocator_v<COMPARATOR>>,
2097 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
2098 >
2099map(std::initializer_list<pair<const KEY, VALUE>>,
2100 COMPARATOR = COMPARATOR(),
2101 ALLOCATOR = ALLOCATOR())
2102-> map<KEY, VALUE, COMPARATOR, ALLOCATOR>;
2103
2104/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
2105/// of the initializer_list supplied to the constructor of `map`. Deduce
2106/// the template parameter `COMPARATOR` from the other parameters passed to
2107/// the constructor. This deduction guide does not participate unless the
2108/// supplied allocator is convertible to
2109/// `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
2110template <
2111 class KEY,
2112 class VALUE,
2113 class COMPARATOR,
2114 class ALLOC,
2115 class DEFAULT_ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
2116 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
2117 >
2118map(std::initializer_list<pair<const KEY, VALUE>>, COMPARATOR, ALLOC *)
2119-> map<KEY, VALUE, COMPARATOR>;
2120
2121/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
2122/// of the initializer_list supplied to the constructor of `map`. Deduce
2123/// the template parameter `ALLOCATOR` from the other parameter passed to
2124/// the constructor. This deduction guide does not participate unless the
2125/// supplied allocator meets the requirements of a standard allocator.
2126template <
2127 class KEY,
2128 class VALUE,
2129 class ALLOCATOR,
2130 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
2131 >
2132map(std::initializer_list<pair<const KEY, VALUE>>, ALLOCATOR)
2133-> map<KEY, VALUE, std::less<KEY>, ALLOCATOR>;
2134
2135/// Deduce the template parameters `KEY` and `VALUE` from the `value_type`
2136/// of the initializer_list supplied to the constructor of `map`. This
2137/// deduction guide does not participate unless the supplied allocator is
2138/// convertible to `bsl::allocator<bsl::pair<const KEY, VALUE>>`.
2139template <
2140 class KEY,
2141 class VALUE,
2142 class ALLOC,
2143 class DEFAULT_ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
2144 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
2145 >
2146map(std::initializer_list<pair<const KEY, VALUE>>, ALLOC *)
2147-> map<KEY, VALUE>;
2148#endif
2149
2150// FREE OPERATORS
2151
2152/// Return `true` if the specified `lhs` and `rhs` objects have the same
2153/// value, and `false` otherwise. Two `map` objects `lhs` and `rhs` have
2154/// the same value if they have the same number of key-value pairs, and each
2155/// element in the ordered sequence of key-value pairs of `lhs` has the same
2156/// value as the corresponding element in the ordered sequence of key-value
2157/// pairs of `rhs`. This method requires that the (template parameter)
2158/// types `KEY` and `VALUE` both be `equality-comparable` (see {Requirements
2159/// on `KEY` and `VALUE`}).
2160template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2161bool operator==(const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
2162 const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
2163
2164#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
2165template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2166bool operator!=(const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
2167 const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
2168 // Return 'true' if the specified 'lhs' and 'rhs' objects do not have the
2169 // same value, and 'false' otherwise. Two 'map' objects 'lhs' and 'rhs' do
2170 // not have the same value if they do not have the same number of key-value
2171 // pairs, or some element in the ordered sequence of key-value pairs of
2172 // 'lhs' does not have the same value as the corresponding element in the
2173 // ordered sequence of key-value pairs of 'rhs'. This method requires that
2174 // the (template parameter) types 'KEY' and 'VALUE' both be
2175 // 'equality-comparable' (see {Requirements on 'KEY' and 'VALUE'}).
2176#endif
2177
2178#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
2179
2180/// Perform a lexicographic three-way comparison of the specified `lhs` and
2181/// the specified `rhs` maps by using the comparison operators of
2182/// `bsl::pair<const KEY, VALUE>` on each element; return the result of that
2183/// comparison.
2184template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2185BloombergLP::bslalg::SynthThreeWayUtil::Result<pair<const KEY, VALUE>>
2186operator<=>(const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
2187 const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
2188
2189#else
2190
2191template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2192bool operator<(const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
2193 const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
2194 // Return 'true' if the value of the specified 'lhs' map is
2195 // lexicographically less than that of the specified 'rhs' map, and 'false'
2196 // otherwise. Given iterators 'i' and 'j' over the respective sequences
2197 // '[lhs.begin() .. lhs.end())' and '[rhs.begin() .. rhs.end())', the value
2198 // of map 'lhs' is lexicographically less than that of map 'rhs' if
2199 // 'true == *i < *j' for the first pair of corresponding iterator positions
2200 // where '*i < *j' and '*j < *i' are not both 'false'. If no such
2201 // corresponding iterator position exists, the value of 'lhs' is
2202 // lexicographically less than that of 'rhs' if 'lhs.size() < rhs.size()'.
2203 // This method requires that 'operator<', inducing a total order, be
2204 // defined for 'value_type'.
2205
2206template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2207bool operator>(const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
2208 const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
2209 // Return 'true' if the value of the specified 'lhs' map is
2210 // lexicographically greater than that of the specified 'rhs' map, and
2211 // 'false' otherwise. The value of map 'lhs' is lexicographically greater
2212 // than that of map 'rhs' if 'rhs' is lexicographically less than 'lhs'
2213 // (see 'operator<'). This method requires that 'operator<', inducing a
2214 // total order, be defined for 'value_type'. Note that this operator
2215 // returns 'rhs < lhs'.
2216
2217template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2218bool operator<=(const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
2219 const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
2220 // Return 'true' if the value of the specified 'lhs' map is
2221 // lexicographically less than or equal to that of the specified 'rhs' map,
2222 // and 'false' otherwise. The value of map 'lhs' is lexicographically less
2223 // than or equal to that of map 'rhs' if 'rhs' is not lexicographically
2224 // less than 'lhs' (see 'operator<'). This method requires that
2225 // 'operator<', inducing a total order, be defined for 'value_type'. Note
2226 // that this operator returns '!(rhs < lhs)'.
2227
2228template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2229bool operator>=(const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
2230 const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
2231 // Return 'true' if the value of the specified 'lhs' map is
2232 // lexicographically greater than or equal to that of the specified 'rhs'
2233 // map, and 'false' otherwise. The value of map 'lhs' is lexicographically
2234 // greater than or equal to that of map 'rhs' if 'lhs' is not
2235 // lexicographically less than 'rhs' (see 'operator<'). This method
2236 // requires that 'operator<', inducing a total order, be defined for
2237 // 'value_type'. Note that this operator returns '!(lhs < rhs)'.
2238
2239#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
2240
2241// FREE FUNCTIONS
2242
2243/// Erase all the elements in the specified map `m` that satisfy the
2244/// specified predicate `predicate`. Return the number of elements erased.
2245template <class KEY,
2246 class VALUE,
2247 class COMPARATOR,
2248 class ALLOCATOR,
2249 class PREDICATE>
2250typename map<KEY, VALUE, COMPARATOR, ALLOCATOR>::size_type
2251erase_if(map<KEY, VALUE, COMPARATOR, ALLOCATOR>& m, PREDICATE predicate);
2252
2253/// Exchange the value and comparator of the specified `a` object with those
2254/// of the specified `b` object; also exchange the allocator of `a` with
2255/// that of `b` if the (template parameter) type `ALLOCATOR` has the
2256/// `propagate_on_container_swap` trait, and do not modify either allocator
2257/// otherwise. This function provides the no-throw exception-safety
2258/// guarantee if and only if the (template parameter) type `COMPARATOR`
2259/// provides a no-throw swap operation, and provides the basic
2260/// exception-safety guarantee otherwise; if an exception is thrown, both
2261/// objects are left in valid but unspecified states. This operation has
2262/// `O[1]` complexity if either `a` was created with the same allocator as
2263/// `b` or `ALLOCATOR` has the `propagate_on_container_swap` trait;
2264/// otherwise, it has `O[n + m]` complexity, where `n` and `m` are the
2265/// number of elements in `a` and `b`, respectively. Note that this
2266/// function's support for swapping objects created with different
2267/// allocators when `ALLOCATOR` does not have the
2268/// `propagate_on_container_swap` trait is a departure from the C++
2269/// Standard.
2270template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2271void swap(map<KEY, VALUE, COMPARATOR, ALLOCATOR>& a,
2272 map<KEY, VALUE, COMPARATOR, ALLOCATOR>& b)
2274
2275// ============================================================================
2276// INLINE FUNCTION DEFINITIONS
2277// ============================================================================
2278
2279 // -----------------
2280 // class DataWrapper
2281 // -----------------
2282
2283// CREATORS
2284template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2285inline
2286map<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::DataWrapper(
2287 const COMPARATOR& comparator,
2288 const ALLOCATOR& basicAllocator)
2289: ::bsl::map<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator(comparator)
2290, d_pool(basicAllocator)
2291{
2292}
2293
2294template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2295inline
2296map<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::DataWrapper(
2297 BloombergLP::bslmf::MovableRef<DataWrapper> original)
2298: ::bsl::map<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator(
2299 MoveUtil::access(original).keyComparator())
2300, d_pool(MoveUtil::move(MoveUtil::access(original).d_pool))
2301{
2302}
2303
2304template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2305inline
2306typename map<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
2307map<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::nodeFactory()
2308{
2309 return d_pool;
2310}
2311
2312// ACCESSORS
2313template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2314inline
2315const typename map<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
2316map<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::nodeFactory() const
2317{
2318 return d_pool;
2319}
2320
2321 // ------------------------
2322 // class map::value_compare
2323 // ------------------------
2324
2325// CREATORS
2326template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2327inline
2329 COMPARATOR comparator)
2330: comp(comparator)
2331{
2332}
2333
2334// ACCESSORS
2335template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2336inline
2338 const value_type& x,
2339 const value_type& y) const
2340{
2341 return comp(x.first, y.first);
2342}
2343
2344 // ---------
2345 // class map
2346 // ---------
2347
2348// PRIVATE CLASS METHODS
2349template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2350inline
2351typename map<KEY, VALUE, COMPARATOR, ALLOCATOR>::Node *
2353 BloombergLP::bslalg::RbTreeNode *node)
2354{
2355 return static_cast<Node *>(node);
2356}
2357
2358template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2359inline
2360const typename map<KEY, VALUE, COMPARATOR, ALLOCATOR>::Node *
2362 const BloombergLP::bslalg::RbTreeNode *node)
2363{
2364 return static_cast<const Node *>(node);
2365}
2366
2367// PRIVATE MANIPULATORS
2368template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2369inline
2370typename map<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
2371map<KEY, VALUE, COMPARATOR, ALLOCATOR>::nodeFactory()
2372{
2373 return d_compAndAlloc.nodeFactory();
2374}
2375
2376template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2377inline
2378typename map<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator&
2379map<KEY, VALUE, COMPARATOR, ALLOCATOR>::comparator()
2380{
2381 return d_compAndAlloc;
2382}
2383
2384template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2385inline
2386void map<KEY, VALUE, COMPARATOR, ALLOCATOR>::quickSwapExchangeAllocators(
2387 map& other)
2388{
2389 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &other.d_tree);
2390 nodeFactory().swapExchangeAllocators(other.nodeFactory());
2391
2392 // 'DataWrapper' contains a 'NodeFactory' object and inherits from
2393 // 'Comparator'. If the empty-base-class optimization has been applied to
2394 // 'Comparator', then we must not call 'swap' on it because
2395 // 'sizeof(Comparator) > 0' and, therefore, we will incorrectly swap bytes
2396 // of the 'NodeFactory' members!
2397
2398 if (sizeof(NodeFactory) != sizeof(DataWrapper)) {
2399 comparator().swap(other.comparator());
2400 }
2401}
2402
2403template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2404inline
2405void map<KEY, VALUE, COMPARATOR, ALLOCATOR>::quickSwapRetainAllocators(
2406 map& other)
2407{
2408 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &other.d_tree);
2409 nodeFactory().swapRetainAllocators(other.nodeFactory());
2410
2411 // See 'quickSwapExchangeAllocators' (above).
2412
2413 if (sizeof(NodeFactory) != sizeof(DataWrapper)) {
2414 comparator().swap(other.comparator());
2415 }
2416}
2417
2418// PRIVATE ACCESSORS
2419template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2420inline
2421const typename map<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
2422map<KEY, VALUE, COMPARATOR, ALLOCATOR>::nodeFactory() const
2423{
2424 return d_compAndAlloc.nodeFactory();
2425}
2426
2427template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2428inline
2429const typename map<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator&
2430map<KEY, VALUE, COMPARATOR, ALLOCATOR>::comparator() const
2431{
2432 return d_compAndAlloc;
2433}
2434
2435// CREATORS
2436template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2437inline
2439: d_compAndAlloc(COMPARATOR(), ALLOCATOR())
2440, d_tree()
2441{
2442}
2443
2444template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2445inline
2446map<KEY, VALUE, COMPARATOR, ALLOCATOR>::map(const ALLOCATOR& basicAllocator)
2447: d_compAndAlloc(COMPARATOR(), basicAllocator)
2448, d_tree()
2449{
2450}
2451
2452template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2453inline
2455: d_compAndAlloc(original.comparator().keyComparator(),
2456 AllocatorTraits::select_on_container_copy_construction(
2457 original.nodeFactory().allocator()))
2458, d_tree()
2459{
2460 if (0 < original.size()) {
2461 nodeFactory().reserveNodes(original.size());
2462 BloombergLP::bslalg::RbTreeUtil::copyTree(&d_tree,
2463 original.d_tree,
2464 &nodeFactory());
2465 }
2466}
2467
2468template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2469inline
2471 BloombergLP::bslmf::MovableRef<map> original)
2472: d_compAndAlloc(MoveUtil::move(MoveUtil::access(original).d_compAndAlloc))
2473, d_tree()
2474{
2475 map& lvalue = original;
2476 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &lvalue.d_tree);
2477}
2478
2479template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2480inline
2482 const typename type_identity<ALLOCATOR>::type& basicAllocator)
2483: d_compAndAlloc(original.comparator().keyComparator(), basicAllocator)
2484, d_tree()
2485{
2486 if (0 < original.size()) {
2487 nodeFactory().reserveNodes(original.size());
2488 BloombergLP::bslalg::RbTreeUtil::copyTree(&d_tree,
2489 original.d_tree,
2490 &nodeFactory());
2491 }
2492}
2493
2494template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2495inline
2497 BloombergLP::bslmf::MovableRef<map> original,
2498 const typename type_identity<ALLOCATOR>::type& basicAllocator)
2499: d_compAndAlloc(MoveUtil::access(original).comparator().keyComparator(),
2500 basicAllocator)
2501, d_tree()
2502{
2503 map& lvalue = original;
2504
2506 nodeFactory().allocator() == lvalue.nodeFactory().allocator())) {
2507 d_compAndAlloc.nodeFactory().adopt(
2508 MoveUtil::move(lvalue.d_compAndAlloc.nodeFactory()));
2509 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &lvalue.d_tree);
2510 }
2511 else if (0 < lvalue.size()) {
2512 nodeFactory().reserveNodes(lvalue.size());
2513 BloombergLP::bslalg::RbTreeUtil::moveTree(&d_tree,
2514 &lvalue.d_tree,
2515 &nodeFactory(),
2516 &lvalue.nodeFactory());
2517 }
2518}
2519
2520template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2521template <class INPUT_ITERATOR>
2522inline
2524 INPUT_ITERATOR last,
2525 const COMPARATOR& comparator,
2526 const ALLOCATOR& basicAllocator)
2527: d_compAndAlloc(comparator, basicAllocator)
2528, d_tree()
2529{
2530 if (first != last) {
2531
2532 size_type numElements =
2533 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last);
2534
2535 if (0 < numElements) {
2536 nodeFactory().reserveNodes(numElements);
2537 }
2538
2539 BloombergLP::bslalg::RbTreeUtilTreeProctor<NodeFactory> proctor(
2540 &d_tree,
2541 &nodeFactory());
2542
2543 // The following loop guarantees amortized linear time to insert an
2544 // ordered sequence of values (as required by the standard). If the
2545 // values are in sorted order, we are guaranteed the next node can be
2546 // inserted as the right child of the previous node, and can call
2547 // 'insertAt' without 'findUniqueInsertLocation'.
2548
2549 insert(*first);
2550 BloombergLP::bslalg::RbTreeNode *prevNode = d_tree.rootNode();
2551 while (++first != last) {
2552 // The values are not in order, so insert them normally.
2553
2554 const value_type& value = *first;
2555 if (this->comparator()(value.first, *prevNode)) {
2556 insert(value);
2557 insert(++first, last);
2558 break;
2559 }
2560
2561 if (this->comparator()(*prevNode, value.first)) {
2562 BloombergLP::bslalg::RbTreeNode *node =
2563 nodeFactory().emplaceIntoNewNode(value);
2564 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2565 prevNode,
2566 false,
2567 node);
2568 prevNode = node;
2569 }
2570 }
2571 proctor.release();
2572 }
2573}
2574
2575template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2576template <class INPUT_ITERATOR>
2577inline
2579 INPUT_ITERATOR last,
2580 const ALLOCATOR& basicAllocator)
2581: d_compAndAlloc(COMPARATOR(), basicAllocator)
2582, d_tree()
2583{
2584 map other(first, last, COMPARATOR(), nodeFactory().allocator());
2585 quickSwapRetainAllocators(other);
2586}
2587
2588#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2589template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2590inline
2592 std::initializer_list<value_type> values,
2593 const COMPARATOR& comparator,
2594 const ALLOCATOR& basicAllocator)
2595: map(values.begin(), values.end(), comparator, basicAllocator)
2596{
2597}
2598
2599template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2600inline
2602 std::initializer_list<value_type> values,
2603 const ALLOCATOR& basicAllocator)
2604: map(values.begin(), values.end(), COMPARATOR(), basicAllocator)
2605{
2606}
2607#endif
2608
2609template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2610inline
2615
2616// MANIPULATORS
2617template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2618inline
2621{
2622 if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this != &rhs)) {
2623 if (AllocatorTraits::propagate_on_container_copy_assignment::value) {
2624 map other(rhs, rhs.nodeFactory().allocator());
2625 quickSwapExchangeAllocators(other);
2626 }
2627 else {
2628 map other(rhs, nodeFactory().allocator());
2629 quickSwapRetainAllocators(other);
2630 }
2631 }
2632 return *this;
2633}
2634
2635template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2636inline
2639 BloombergLP::bslmf::MovableRef<map> rhs)
2641 AllocatorTraits::is_always_equal::value &&
2642 std::is_nothrow_move_assignable<COMPARATOR>::value)
2643{
2644 map& lvalue = rhs;
2645
2646 if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(this != &lvalue)) {
2647 if (nodeFactory().allocator() == lvalue.nodeFactory().allocator()) {
2648 map other(MoveUtil::move(lvalue));
2649 quickSwapRetainAllocators(other);
2650 }
2651 else if (
2652 AllocatorTraits::propagate_on_container_move_assignment::value) {
2653 map other(MoveUtil::move(lvalue));
2654 quickSwapExchangeAllocators(other);
2655 }
2656 else {
2657 map other(MoveUtil::move(lvalue), nodeFactory().allocator());
2658 quickSwapRetainAllocators(other);
2659 }
2660 }
2661 return *this;
2662}
2663
2664#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2665template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2666inline
2667map<KEY, VALUE, COMPARATOR, ALLOCATOR>&
2669 std::initializer_list<value_type> values)
2670{
2671 clear();
2672 insert(values.begin(), values.end());
2673 return *this;
2674}
2675#endif
2676
2677template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2678inline
2681{
2682 iterator iter = lower_bound(key);
2683 if (iter == end() || this->comparator()(key, *iter.node())) {
2684#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
2685 iter = emplace_hint(iter,
2686 std::piecewise_construct,
2687 std::forward_as_tuple(key),
2688 std::forward_as_tuple());
2689#else
2690 BloombergLP::bsls::ObjectBuffer<VALUE> temp; // for default 'VALUE'
2691
2692 ALLOCATOR alloc = nodeFactory().allocator();
2693
2694 AllocatorTraits::construct(alloc, temp.address());
2695
2696 BloombergLP::bslma::DestructorGuard<VALUE> guard(temp.address());
2697
2698 iter = emplace_hint(iter, key, temp.object());
2699#endif
2700 }
2701 return iter->second;
2702}
2703
2704template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2705inline
2708 BloombergLP::bslmf::MovableRef<key_type> key)
2709{
2710 key_type& lvalue = key;
2711
2712 iterator iter = lower_bound(lvalue);
2713 if (iter == end() || this->comparator()(lvalue, *iter.node())) {
2714#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
2715 iter = emplace_hint(
2716 iter,
2717 std::piecewise_construct,
2718 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(key_type, key)),
2719 std::forward_as_tuple());
2720#else
2721 BloombergLP::bsls::ObjectBuffer<VALUE> temp; // for default 'VALUE'
2722
2723 ALLOCATOR alloc = nodeFactory().allocator();
2724
2725 AllocatorTraits::construct(alloc, temp.address());
2726
2727 BloombergLP::bslma::DestructorGuard<VALUE> guard(temp.address());
2728
2729 iter = emplace_hint(iter, lvalue, temp.object());
2730#endif
2731 }
2732 return iter->second;
2733}
2734
2735template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2738{
2739 BloombergLP::bslalg::RbTreeNode *node =
2740 BloombergLP::bslalg::RbTreeUtil::find(d_tree, this->comparator(), key);
2741 if (d_tree.sentinel() == node) {
2742 BloombergLP::bslstl::StdExceptUtil::throwOutOfRange(
2743 "map<...>::at(key_type): invalid key value");
2744 }
2745 return toNode(node)->value().second;
2746}
2747
2748template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2749inline
2755
2756template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2757inline
2763
2764template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2765inline
2771
2772template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2773inline
2779
2780template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2781inline
2784{
2785 int comparisonResult;
2786 BloombergLP::bslalg::RbTreeNode *insertLocation =
2787 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
2788 &comparisonResult,
2789 &d_tree,
2790 this->comparator(),
2791 value.first);
2792 if (!comparisonResult) {
2793 return pair<iterator, bool>(iterator(insertLocation), false); // RETURN
2794 }
2795
2796 BloombergLP::bslalg::RbTreeNode *node =
2797 nodeFactory().emplaceIntoNewNode(value);
2798 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2799 insertLocation,
2800 comparisonResult < 0,
2801 node);
2802 return pair<iterator, bool>(iterator(node), true);
2803}
2804
2805template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2806inline
2809 BloombergLP::bslmf::MovableRef<value_type> value)
2810{
2811 value_type& lvalue = value;
2812
2813 int comparisonResult;
2814 BloombergLP::bslalg::RbTreeNode *insertLocation =
2815 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
2816 &comparisonResult,
2817 &d_tree,
2818 this->comparator(),
2819 lvalue.first);
2820 if (!comparisonResult) {
2821 return pair<iterator, bool>(iterator(insertLocation), false); // RETURN
2822 }
2823
2824 BloombergLP::bslalg::RbTreeNode *node =
2825 nodeFactory().emplaceIntoNewNode(MoveUtil::move(lvalue));
2826 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2827 insertLocation,
2828 comparisonResult < 0,
2829 node);
2830 return pair<iterator, bool>(iterator(node), true);
2831}
2832
2833template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2834template <class INPUT_ITERATOR>
2835inline
2837 INPUT_ITERATOR last)
2838{
2839 ///Implementation Notes
2840 ///--------------------
2841 // First, consume currently held free nodes. If those nodes are
2842 // insufficient *and* one can calculate the remaining number of elements,
2843 // then reserve exactly that many free nodes. There is no more than one
2844 // call to 'reserveNodes' per invocation of this method, hence the use of
2845 // 'BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY'. When reserving nodes, we
2846 // assume the elements remaining to be inserted have unique keys that do
2847 // not duplicate any keys already in the container. If there are any
2848 // duplicates, this container will have free nodes on return from this
2849 // method.
2850
2851 const bool canCalculateInsertDistance =
2852 is_convertible<typename
2853 iterator_traits<INPUT_ITERATOR>::iterator_category,
2854 forward_iterator_tag>::value;
2855
2856 while (first != last) {
2857 if (canCalculateInsertDistance
2859 !nodeFactory().hasFreeNodes())) {
2860 const size_type numElements =
2861 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last);
2862
2863 nodeFactory().reserveNodes(numElements);
2864 }
2865 insert(*first);
2866 ++first;
2867 }
2868}
2869
2870#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
2871template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2872inline
2873void map<KEY, VALUE, COMPARATOR, ALLOCATOR>::insert(const_iterator first,
2874 const_iterator last)
2875{
2876 while (first != last) {
2877 insert(*first);
2878 ++first;
2879 }
2880}
2881#endif
2882
2883template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2884inline
2887 const value_type& value)
2888{
2889 BloombergLP::bslalg::RbTreeNode *hintNode =
2890 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
2891 int comparisonResult;
2892 BloombergLP::bslalg::RbTreeNode *insertLocation =
2893 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
2894 &comparisonResult,
2895 &d_tree,
2896 this->comparator(),
2897 value.first,
2898 hintNode);
2899 if (!comparisonResult) {
2900 return iterator(insertLocation); // RETURN
2901 }
2902
2903 BloombergLP::bslalg::RbTreeNode *node =
2904 nodeFactory().emplaceIntoNewNode(value);
2905 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2906 insertLocation,
2907 comparisonResult < 0,
2908 node);
2909 return iterator(node);
2910}
2911
2912template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2913inline
2916 const_iterator hint,
2917 BloombergLP::bslmf::MovableRef<value_type> value)
2918{
2919 value_type& lvalue = value;
2920
2921 BloombergLP::bslalg::RbTreeNode *hintNode =
2922 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
2923 int comparisonResult;
2924 BloombergLP::bslalg::RbTreeNode *insertLocation =
2925 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
2926 &comparisonResult,
2927 &d_tree,
2928 this->comparator(),
2929 lvalue.first,
2930 hintNode);
2931 if (!comparisonResult) {
2932 return iterator(insertLocation); // RETURN
2933 }
2934
2935 BloombergLP::bslalg::RbTreeNode *node =
2936 nodeFactory().emplaceIntoNewNode(MoveUtil::move(lvalue));
2937
2938 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2939 insertLocation,
2940 comparisonResult < 0,
2941 node);
2942 return iterator(node);
2943}
2944
2945#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2946template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2947inline
2949 std::initializer_list<value_type> values)
2950{
2951 insert(values.begin(), values.end());
2952}
2953#endif
2954
2955#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
2956template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2957template <class BDE_OTHER_TYPE>
2958inline
2959pair<typename map<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator, bool>
2961 BDE_OTHER_TYPE&& obj)
2962{
2963 int comparisonResult;
2964 BloombergLP::bslalg::RbTreeNode *insertLocation =
2965 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
2966 &comparisonResult,
2967 &d_tree,
2968 this->comparator(),
2969 key);
2970
2971 if (!comparisonResult) { // ASSIGN
2972 iterator(insertLocation)->second =
2973 BSLS_COMPILERFEATURES_FORWARD(BDE_OTHER_TYPE, obj);
2974 return pair<iterator, bool>(iterator(insertLocation), false); // RETURN
2975 }
2976
2977 // INSERT
2978 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2979 key, BSLS_COMPILERFEATURES_FORWARD(BDE_OTHER_TYPE, obj));
2980
2981 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2982 insertLocation,
2983 comparisonResult < 0,
2984 node);
2985
2986 return pair<iterator, bool>(iterator(node), true);
2987}
2988
2989template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
2990template <class BDE_OTHER_TYPE>
2991inline
2994 const key_type& key,
2995 BDE_OTHER_TYPE&& obj)
2996{
2997 BloombergLP::bslalg::RbTreeNode *hintNode =
2998 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
2999 int comparisonResult;
3000 BloombergLP::bslalg::RbTreeNode *insertLocation =
3001 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
3002 &comparisonResult,
3003 &d_tree,
3004 this->comparator(),
3005 key,
3006 hintNode);
3007
3008 if (!comparisonResult) { // ASSIGN
3009 iterator(insertLocation)->second =
3010 BSLS_COMPILERFEATURES_FORWARD(BDE_OTHER_TYPE, obj);
3011 return iterator(insertLocation); // RETURN
3012 }
3013
3014 // INSERT
3015 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3016 key, BSLS_COMPILERFEATURES_FORWARD(BDE_OTHER_TYPE, obj));
3017
3018 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3019 insertLocation,
3020 comparisonResult < 0,
3021 node);
3022
3023 return iterator(node);
3024}
3025
3026template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3027template <class BDE_OTHER_TYPE>
3028inline
3031 BloombergLP::bslmf::MovableRef<key_type> key,
3032 BDE_OTHER_TYPE&& obj)
3033{
3034 int comparisonResult;
3035 BloombergLP::bslalg::RbTreeNode *insertLocation =
3036 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
3037 &comparisonResult,
3038 &d_tree,
3039 this->comparator(),
3040 key);
3041
3042 if (!comparisonResult) { // ASSIGN
3043 iterator(insertLocation)->second =
3044 BSLS_COMPILERFEATURES_FORWARD(BDE_OTHER_TYPE, obj);
3045 return pair<iterator, bool>(iterator(insertLocation), false); // RETURN
3046 }
3047
3048 // INSERT
3049 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3051 BSLS_COMPILERFEATURES_FORWARD(BDE_OTHER_TYPE, obj));
3052
3053 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3054 insertLocation,
3055 comparisonResult < 0,
3056 node);
3057
3058 return pair<iterator, bool>(iterator(node), true);
3059}
3060
3061template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3062template <class BDE_OTHER_TYPE>
3063inline
3066 const_iterator hint,
3067 BloombergLP::bslmf::MovableRef<key_type> key,
3068 BDE_OTHER_TYPE&& obj)
3069{
3070 BloombergLP::bslalg::RbTreeNode *hintNode =
3071 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
3072 int comparisonResult;
3073 BloombergLP::bslalg::RbTreeNode *insertLocation =
3074 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
3075 &comparisonResult,
3076 &d_tree,
3077 this->comparator(),
3078 key,
3079 hintNode);
3080
3081 if (!comparisonResult) { // ASSIGN
3082 iterator(insertLocation)->second =
3083 BSLS_COMPILERFEATURES_FORWARD(BDE_OTHER_TYPE, obj);
3084 return iterator(insertLocation); // RETURN
3085 }
3086
3087 // INSERT
3088 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3090 BSLS_COMPILERFEATURES_FORWARD(BDE_OTHER_TYPE, obj));
3091
3092 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3093 insertLocation,
3094 comparisonResult < 0,
3095 node);
3096
3097 return iterator(node);
3098}
3099#endif
3100
3101#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3102
3103template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3104template <class... Args>
3105inline
3108{
3109 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3110 BSLS_COMPILERFEATURES_FORWARD(Args, args)...);
3111 int comparisonResult;
3112 BloombergLP::bslalg::RbTreeNode *insertLocation =
3113 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
3114 &comparisonResult,
3115 &d_tree,
3116 this->comparator(),
3117 static_cast<const Node *>(node)->value().first);
3118 if (!comparisonResult) {
3119 nodeFactory().deleteNode(node);
3120 return pair<iterator, bool>(iterator(insertLocation), false); // RETURN
3121 }
3122
3123 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3124 insertLocation,
3125 comparisonResult < 0,
3126 node);
3127 return pair<iterator, bool>(iterator(node), true);
3128}
3129
3130template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3131template <class... Args>
3132inline
3135 Args&&... args)
3136{
3137 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3138 BSLS_COMPILERFEATURES_FORWARD(Args, args)...);
3139 BloombergLP::bslalg::RbTreeNode *hintNode =
3140 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
3141 int comparisonResult;
3142 BloombergLP::bslalg::RbTreeNode *insertLocation =
3143 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
3144 &comparisonResult,
3145 &d_tree,
3146 this->comparator(),
3147 static_cast<const Node *>(node)->value().first,
3148 hintNode);
3149 if (!comparisonResult) {
3150 nodeFactory().deleteNode(node);
3151 return iterator(insertLocation); // RETURN
3152 }
3153
3154 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3155 insertLocation,
3156 comparisonResult < 0,
3157 node);
3158 return iterator(node);
3159}
3160
3161#endif
3162
3163template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3164inline
3167{
3168 BSLS_ASSERT_SAFE(position != end());
3169
3170 BloombergLP::bslalg::RbTreeNode *node =
3171 const_cast<BloombergLP::bslalg::RbTreeNode *>(position.node());
3172 BloombergLP::bslalg::RbTreeNode *result =
3173 BloombergLP::bslalg::RbTreeUtil::next(node);
3174 BloombergLP::bslalg::RbTreeUtil::remove(&d_tree, node);
3175 nodeFactory().deleteNode(node);
3176 return iterator(result);
3177}
3178
3179template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3180inline
3186
3187template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3188inline
3191{
3192 const_iterator it = find(key);
3193 if (it == end()) {
3194 return 0; // RETURN
3195 }
3196 erase(it);
3197 return 1;
3198}
3199
3200template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3201inline
3204 const_iterator last)
3205{
3206 while (first != last) {
3207 first = erase(first);
3208 }
3209 return iterator(last.node());
3210}
3211
3212template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3213inline
3216 AllocatorTraits::is_always_equal::value &&
3217 bsl::is_nothrow_swappable<COMPARATOR>::value)
3218{
3219 if (AllocatorTraits::propagate_on_container_swap::value) {
3220 quickSwapExchangeAllocators(other);
3221 }
3222 else {
3223 // C++11 behavior for member 'swap': undefined for unequal allocators.
3224 // BSLS_ASSERT(allocator() == other.allocator());
3225
3227 nodeFactory().allocator() == other.nodeFactory().allocator())) {
3228 quickSwapRetainAllocators(other);
3229 }
3230 else {
3232
3233 map toOtherCopy(MoveUtil::move(*this),
3234 other.nodeFactory().allocator());
3235 map toThisCopy(MoveUtil::move(other), nodeFactory().allocator());
3236
3237 this->quickSwapRetainAllocators(toThisCopy);
3238 other.quickSwapRetainAllocators(toOtherCopy);
3239 }
3240 }
3241}
3242
3243#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3244template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3245template <class... Args>
3246inline
3247pair<typename map<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator, bool>
3249 Args&&... args)
3250{
3251 int comparisonResult;
3252 BloombergLP::bslalg::RbTreeNode *insertLocation =
3253 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
3254 &comparisonResult,
3255 &d_tree,
3256 this->comparator(),
3257 key);
3258 if (!comparisonResult) {
3259 return pair<iterator, bool>(iterator(insertLocation), false); // RETURN
3260 }
3261
3262#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
3263 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3264 std::piecewise_construct,
3265 std::forward_as_tuple(key),
3266 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(Args, args)...));
3267#else
3268 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3269 key,
3271#endif
3272
3273 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3274 insertLocation,
3275 comparisonResult < 0,
3276 node);
3277 return pair<iterator, bool>(iterator(node), true);
3278}
3279
3280template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3281template <class... Args>
3282inline
3285 const key_type& key,
3286 Args&&... args)
3287{
3288 BloombergLP::bslalg::RbTreeNode *hintNode =
3289 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
3290 int comparisonResult;
3291 BloombergLP::bslalg::RbTreeNode *insertLocation =
3292 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
3293 &comparisonResult,
3294 &d_tree,
3295 this->comparator(),
3296 key,
3297 hintNode);
3298 if (!comparisonResult) {
3299 return iterator(insertLocation); // RETURN
3300 }
3301
3302#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
3303 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3304 std::piecewise_construct,
3305 std::forward_as_tuple(key),
3306 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(Args, args)...));
3307#else
3308 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3309 key,
3311#endif
3312
3313 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3314 insertLocation,
3315 comparisonResult < 0,
3316 node);
3317 return iterator(node);
3318}
3319
3320template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3321template <class... Args>
3322inline
3325 BloombergLP::bslmf::MovableRef<key_type> key,
3326 Args&&... args)
3327{
3328 key_type& lvalue = key;
3329
3330 int comparisonResult;
3331 BloombergLP::bslalg::RbTreeNode *insertLocation =
3332 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
3333 &comparisonResult,
3334 &d_tree,
3335 this->comparator(),
3336 lvalue);
3337 if (!comparisonResult) {
3338 return pair<iterator, bool>(iterator(insertLocation), false); // RETURN
3339 }
3340
3341#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
3342 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3343 std::piecewise_construct,
3344 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(key_type, key)),
3345 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(Args, args)...));
3346#else
3347 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3350#endif
3351
3352 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3353 insertLocation,
3354 comparisonResult < 0,
3355 node);
3356
3357 return pair<iterator, bool>(iterator(node), true);
3358}
3359
3360template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3361template <class... Args>
3362inline
3365 const_iterator hint,
3366 BloombergLP::bslmf::MovableRef<key_type> key,
3367 Args&&... args)
3368{
3369 key_type& lvalue = key;
3370
3371 BloombergLP::bslalg::RbTreeNode *hintNode =
3372 const_cast<BloombergLP::bslalg::RbTreeNode *>(hint.node());
3373 int comparisonResult;
3374 BloombergLP::bslalg::RbTreeNode *insertLocation =
3375 BloombergLP::bslalg::RbTreeUtil::findUniqueInsertLocation(
3376 &comparisonResult,
3377 &d_tree,
3378 this->comparator(),
3379 lvalue,
3380 hintNode);
3381 if (!comparisonResult) {
3382 return iterator(insertLocation); // RETURN
3383 }
3384
3385#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
3386 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3387 std::piecewise_construct,
3388 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(key_type, key)),
3389 std::forward_as_tuple(BSLS_COMPILERFEATURES_FORWARD(Args, args)...));
3390#else
3391 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
3394#endif
3395
3396 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
3397 insertLocation,
3398 comparisonResult < 0,
3399 node);
3400 return iterator(node);
3401}
3402#endif
3403
3404template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3405inline
3407{
3408 BSLS_ASSERT_SAFE(d_tree.firstNode());
3409
3410 if (d_tree.rootNode()) {
3411 BSLS_ASSERT_SAFE( 0 < d_tree.numNodes());
3412 BSLS_ASSERT_SAFE(d_tree.firstNode() != d_tree.sentinel());
3413
3414 BloombergLP::bslalg::RbTreeUtil::deleteTree(&d_tree, &nodeFactory());
3415 }
3416#if defined(BSLS_ASSERT_SAFE_IS_USED)
3417 else {
3418 BSLS_ASSERT_SAFE( 0 == d_tree.numNodes());
3419 BSLS_ASSERT_SAFE(d_tree.firstNode() == d_tree.sentinel());
3420 }
3421#endif
3422}
3423
3424// ACCESSORS
3425template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3426inline
3430{
3431 return nodeFactory().allocator();
3432}
3433
3434template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3435inline
3441
3442template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3443inline
3449
3450template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3451inline
3457
3458template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3459inline
3465
3466template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3467inline
3473
3474template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3475inline
3481
3482template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3483inline
3489
3490template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3491inline
3497
3498template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3499inline
3501 const key_type& key) const
3502{
3503 return find(key) != end();
3504}
3505
3506// capacity:
3507template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3508inline
3511{
3512 return 0 == d_tree.numNodes();
3513}
3514
3515template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3516inline
3519{
3520 return d_tree.numNodes();
3521}
3522
3523template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3524inline
3527{
3528 return AllocatorTraits::max_size(get_allocator());
3529}
3530
3531template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3534 const key_type& key) const
3535{
3536 const BloombergLP::bslalg::RbTreeNode *node =
3537 BloombergLP::bslalg::RbTreeUtil::find(d_tree,
3538 this->comparator(),
3539 key);
3540 if (d_tree.sentinel() == node) {
3541 BloombergLP::bslstl::StdExceptUtil::throwOutOfRange(
3542 "map<...>::at(key_type): invalid key value");
3543 }
3544 return toNode(node)->value().second;
3545}
3546
3547template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3548inline
3551{
3552 return comparator().keyComparator();
3553}
3554
3555template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3556inline
3559{
3560 return value_compare(key_comp());
3561}
3562
3563} // close namespace bsl
3564
3565// FREE OPERATORS
3566template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3567inline
3568bool bsl::operator==(const bsl::map<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
3570{
3571 return BloombergLP::bslalg::RangeCompare::equal(lhs.begin(),
3572 lhs.end(),
3573 lhs.size(),
3574 rhs.begin(),
3575 rhs.end(),
3576 rhs.size());
3577}
3578
3579#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
3580template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3581inline
3584{
3585 return !(lhs == rhs);
3586}
3587#endif
3588
3589#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
3590
3591template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3592inline
3593BloombergLP::bslalg::SynthThreeWayUtil::Result<bsl::pair<const KEY, VALUE>>
3594bsl::operator<=>(const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
3595 const map<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs)
3596{
3597 return bsl::lexicographical_compare_three_way(
3598 lhs.begin(),
3599 lhs.end(),
3600 rhs.begin(),
3601 rhs.end(),
3602 BloombergLP::bslalg::SynthThreeWayUtil::compare);
3603}
3604
3605#else
3606
3607template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3608inline
3611{
3612 return 0 > BloombergLP::bslalg::RangeCompare::lexicographical(lhs.begin(),
3613 lhs.end(),
3614 lhs.size(),
3615 rhs.begin(),
3616 rhs.end(),
3617 rhs.size());
3618}
3619
3620template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3621inline
3624{
3625 return rhs < lhs;
3626}
3627
3628template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3629inline
3632{
3633 return !(rhs < lhs);
3634}
3635
3636template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3637inline
3640{
3641 return !(lhs < rhs);
3642}
3643
3644#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
3645
3646// FREE FUNCTIONS
3647template <class KEY,
3648 class VALUE,
3649 class COMPARATOR,
3650 class ALLOCATOR,
3651 class PREDICATE>
3652inline
3654bsl::erase_if(map<KEY, VALUE, COMPARATOR, ALLOCATOR>& m, PREDICATE predicate)
3655{
3656 return BloombergLP::bslstl::AlgorithmUtil::containerEraseIf(m, predicate);
3657}
3658
3659template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3660inline
3664{
3665 a.swap(b);
3666}
3667
3668// ============================================================================
3669// TYPE TRAITS
3670// ============================================================================
3671
3672// Type traits for STL *ordered* containers:
3673//: o An ordered container defines STL iterators.
3674//: o An ordered container uses 'bslma' allocators if the (template parameter)
3675//: type 'ALLOCATOR' is convertible from 'bslma::Allocator *'.
3676
3677
3678
3679namespace bslalg {
3680
3681template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3682struct HasStlIterators<bsl::map<KEY, VALUE, COMPARATOR, ALLOCATOR> >
3684{
3685};
3686
3687} // close namespace bslalg
3688
3689namespace bslma {
3690
3691template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
3692struct UsesBslmaAllocator<bsl::map<KEY, VALUE, COMPARATOR, ALLOCATOR> >
3693 : bsl::is_convertible<Allocator *, ALLOCATOR>
3694{
3695};
3696
3697} // close namespace bslma
3698
3699
3700
3701#endif // End C++11 code
3702
3703#endif
3704
3705// ----------------------------------------------------------------------------
3706// Copyright 2019 Bloomberg Finance L.P.
3707//
3708// Licensed under the Apache License, Version 2.0 (the "License");
3709// you may not use this file except in compliance with the License.
3710// You may obtain a copy of the License at
3711//
3712// http://www.apache.org/licenses/LICENSE-2.0
3713//
3714// Unless required by applicable law or agreed to in writing, software
3715// distributed under the License is distributed on an "AS IS" BASIS,
3716// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3717// See the License for the specific language governing permissions and
3718// limitations under the License.
3719// ----------------------------- END-OF-FILE ----------------------------------
3720
3721/** @} */
3722/** @} */
3723/** @} */
Definition bslma_bslallocator.h:580
Definition bslstl_string.h:1281
Definition bslstl_map.h:736
value_compare(const value_compare &original)=default
value_type second_argument_type
Definition bslstl_map.h:768
COMPARATOR comp
Definition bslstl_map.h:743
bool operator()(const value_type &x, const value_type &y) const
Definition bslstl_map.h:2337
value_type first_argument_type
Definition bslstl_map.h:763
value_compare & operator=(const value_compare &rhs)=default
bool result_type
Definition bslstl_map.h:758
Definition bslstl_map.h:619
value_type & reference
Definition bslstl_map.h:713
iterator erase(const_iterator position)
Definition bslstl_map.h:3166
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_map.h:3428
enable_if< is_convertible< ALT_VALUE_TYPE, value_type >::value, iterator >::type insert(const_iterator hint, BSLS_COMPILERFEATURES_FORWARD_REF(ALT_VALUE_TYPE) value)
Definition bslstl_map.h:1207
const_reverse_iterator crend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_map.h:3493
void insert(INPUT_ITERATOR first, INPUT_ITERATOR last)
Definition bslstl_map.h:2836
map &operator=(BloombergLP::bslmf::MovableRef< map > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits add_lvalue_reference< VALUE >::type operator[](const key_type &key)
Definition bslstl_map.h:2680
bool contains(const key_type &key) const
Definition bslstl_map.h:3500
BloombergLP::bslstl::TreeIterator< const value_type, Node, difference_type > const_iterator
Definition bslstl_map.h:724
reverse_iterator rend() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_map.h:2775
pair< iterator, iterator > equal_range(const key_type &key)
Definition bslstl_map.h:1651
iterator erase(const_iterator first, const_iterator last)
Definition bslstl_map.h:3203
iterator upper_bound(const key_type &key)
Definition bslstl_map.h:1612
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, const_iterator >::type lower_bound(const LOOKUP_KEY &key) const
Definition bslstl_map.h:1900
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_map.h:2759
iterator try_emplace(const_iterator hint, const KEY &key, Args &&... args)
Definition bslstl_map.h:3284
map()
Definition bslstl_map.h:2438
~map()
Destroy this object.
Definition bslstl_map.h:2611
const_reverse_iterator crbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_map.h:3485
size_type erase(const key_type &key)
Definition bslstl_map.h:3190
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, iterator >::type find(const LOOKUP_KEY &key)
Definition bslstl_map.h:1559
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value &&!bsl::is_convertible< LOOKUP_KEY &&, const_iterator >::value &&!bsl::is_convertible< LOOKUP_KEY &&, iterator >::value, pair< iterator, bool > >::type try_emplace(LOOKUP_KEY &&key, Args &&... args)
Definition bslstl_map.h:1427
reverse_iterator rbegin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_map.h:2767
iterator lower_bound(const key_type &key)
Definition bslstl_map.h:1575
size_type count(const key_type &key) const
Definition bslstl_map.h:1839
const value_type & const_reference
Definition bslstl_map.h:714
KEY key_type
Definition bslstl_map.h:708
pair< iterator, bool > insert_or_assign(BloombergLP::bslmf::MovableRef< KEY > key, BDE_OTHER_TYPE &&obj)
map(const ALLOCATOR &basicAllocator)
Definition bslstl_map.h:2446
iterator insert(const_iterator hint, BloombergLP::bslmf::MovableRef< value_type > value)
Definition bslstl_map.h:2915
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, iterator >::type lower_bound(const LOOKUP_KEY &key)
Definition bslstl_map.h:1596
AllocatorTraits::const_pointer const_pointer
Definition bslstl_map.h:719
add_lvalue_reference< VALUE >::type at(const key_type &key)
Definition bslstl_map.h:2737
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, pair< iterator, iterator > >::type equal_range(const LOOKUP_KEY &key)
Definition bslstl_map.h:1681
iterator insert_or_assign(const_iterator hint, const KEY &key, BDE_OTHER_TYPE &&obj)
Definition bslstl_map.h:2993
pair< iterator, bool > emplace(Args &&... args)
map(BloombergLP::bslmf::MovableRef< map > original, const typename type_identity< ALLOCATOR >::type &basicAllocator)
Definition bslstl_map.h:2496
map(const map &original, const typename type_identity< ALLOCATOR >::type &basicAllocator)
Definition bslstl_map.h:2481
bsl::reverse_iterator< iterator > reverse_iterator
Definition bslstl_map.h:725
iterator find(const key_type &key)
Definition bslstl_map.h:1542
void swap(map &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits pair< iterator, bool > try_emplace(const KEY &key, Args &&... args)
Definition bslstl_map.h:1416
ALLOCATOR allocator_type
Definition bslstl_map.h:712
map & operator=(const map &rhs)
Definition bslstl_map.h:2620
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, const_iterator >::type find(const LOOKUP_KEY &key) const
Definition bslstl_map.h:1828
bool empty() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_map.h:3509
pair< iterator, bool > insert_or_assign(const KEY &key, BDE_OTHER_TYPE &&obj)
iterator erase(iterator position)
Definition bslstl_map.h:3182
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this map.
Definition bslstl_map.h:3518
map(BloombergLP::bslmf::MovableRef< map > original)
Definition bslstl_map.h:2470
pair< iterator, bool > insert(const value_type &value)
Definition bslstl_map.h:2783
iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_map.h:2751
VALUE mapped_type
Definition bslstl_map.h:709
map(const COMPARATOR &comparator, const ALLOCATOR &basicAllocator=ALLOCATOR())
Definition bslstl_map.h:855
pair< const_iterator, const_iterator > equal_range(const key_type &key) const
Definition bslstl_map.h:1957
void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_map.h:3406
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, size_type >::type count(const LOOKUP_KEY &key) const
Definition bslstl_map.h:1857
pair< iterator, bool > try_emplace(BloombergLP::bslmf::MovableRef< KEY > key, Args &&... args)
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, iterator >::type try_emplace(const_iterator hint, LOOKUP_KEY &&key, Args &&... args)
Definition bslstl_map.h:1486
add_lvalue_reference< VALUE >::type operator[](BloombergLP::bslmf::MovableRef< key_type > key)
Definition bslstl_map.h:2707
value_compare value_comp() const
Definition bslstl_map.h:3558
const_iterator cbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_map.h:3469
size_type max_size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_map.h:3526
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, iterator >::type upper_bound(const LOOKUP_KEY &key)
Definition bslstl_map.h:1633
iterator insert_or_assign(const_iterator hint, BloombergLP::bslmf::MovableRef< KEY > key, BDE_OTHER_TYPE &&obj)
Definition bslstl_map.h:3065
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, pair< const_iterator, const_iterator > >::type equal_range(const LOOKUP_KEY &key) const
Definition bslstl_map.h:1987
map(INPUT_ITERATOR first, INPUT_ITERATOR last, const COMPARATOR &comparator=COMPARATOR(), const ALLOCATOR &basicAllocator=ALLOCATOR())
Definition bslstl_map.h:2523
bsl::reverse_iterator< const_iterator > const_reverse_iterator
Definition bslstl_map.h:726
enable_if< is_convertible< ALT_VALUE_TYPE, value_type >::value, pair< iterator, bool > >::type insert(BSLS_COMPILERFEATURES_FORWARD_REF(ALT_VALUE_TYPE) value)
Definition bslstl_map.h:1135
AllocatorTraits::size_type size_type
Definition bslstl_map.h:716
iterator emplace_hint(const_iterator hint, Args &&... args)
Definition bslstl_map.h:3134
const_iterator cend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_map.h:3477
BloombergLP::bslstl::TreeIterator< value_type, Node, difference_type > iterator
Definition bslstl_map.h:722
pair< const KEY, VALUE > value_type
Definition bslstl_map.h:710
iterator insert(const_iterator hint, const value_type &value)
Definition bslstl_map.h:2886
bsl::enable_if< BloombergLP::bslmf::IsTransparentPredicate< COMPARATOR, LOOKUP_KEY >::value, const_iterator >::type upper_bound(const LOOKUP_KEY &key) const
Definition bslstl_map.h:1939
AllocatorTraits::pointer pointer
Definition bslstl_map.h:718
AllocatorTraits::difference_type difference_type
Definition bslstl_map.h:717
key_compare key_comp() const
Definition bslstl_map.h:3550
const_iterator upper_bound(const key_type &key) const
Definition bslstl_map.h:1918
map(INPUT_ITERATOR first, INPUT_ITERATOR last, const ALLOCATOR &basicAllocator)
Definition bslstl_map.h:2578
map(const map &original)
Definition bslstl_map.h:2454
iterator try_emplace(const_iterator hint, BloombergLP::bslmf::MovableRef< KEY > key, Args &&... args)
Definition bslstl_map.h:3364
const_iterator lower_bound(const key_type &key) const
Definition bslstl_map.h:1879
COMPARATOR key_compare
Definition bslstl_map.h:711
Definition bslstl_pair.h:1210
#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_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:634
#define BSLS_PERFORMANCEHINT_PREDICT_LIKELY(expr)
Definition bsls_performancehint.h:451
#define BSLS_PERFORMANCEHINT_UNLIKELY_HINT
Definition bsls_performancehint.h:484
#define BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
Definition bdlb_printmethods.h:283
void swap(array< VALUE_TYPE, SIZE > &lhs, array< VALUE_TYPE, SIZE > &rhs)
T::const_iterator cend(const T &container)
Definition bslstl_iterator.h:1611
bool operator<(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
T::const_reverse_iterator crbegin(const T &container)
Definition bslstl_iterator.h:1597
bool operator>(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
bool operator>=(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
bool operator<=(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
deque< VALUE_TYPE, ALLOCATOR >::size_type erase(deque< VALUE_TYPE, ALLOCATOR > &deq, const BDE_OTHER_TYPE &value)
Definition bslstl_deque.h:4126
T::iterator begin(T &container)
Definition bslstl_iterator.h:1495
T::const_iterator cbegin(const T &container)
Definition bslstl_iterator.h:1553
T::iterator end(T &container)
Definition bslstl_iterator.h:1523
deque< VALUE_TYPE, ALLOCATOR >::size_type erase_if(deque< VALUE_TYPE, ALLOCATOR > &deq, PREDICATE predicate)
Definition bslstl_deque.h:4135
bool operator!=(const memory_resource &a, const memory_resource &b)
T::const_reverse_iterator crend(const T &container)
Definition bslstl_iterator.h:1654
Definition bdlc_flathashmap.h:1805
Definition balxml_encoderoptions.h:68
Definition bdlbb_blob.h:576
TYPE first
Definition bslstl_pair.h:605
Definition bslmf_addlvaluereference.h:126
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_ConstPointerType< ALLOCATOR >::type const_pointer
Definition bslma_allocatortraits.h:1152
BloombergLP::bslma::AllocatorTraits_SizeType< ALLOCATOR >::type size_type
Definition bslma_allocatortraits.h:1165
BloombergLP::bslma::AllocatorTraits_PointerType< ALLOCATOR >::type pointer
Definition bslma_allocatortraits.h:1149
BloombergLP::bslma::AllocatorTraits_DifferenceType< ALLOCATOR >::type difference_type
Definition bslma_allocatortraits.h:1162
Definition bslmf_enableif.h:525
Definition bslmf_isconvertible.h:867
t_TYPE type
Definition bslmf_typeidentity.h:216
Definition bslalg_hasstliterators.h:99
Definition bslma_usesbslmaallocator.h:343