BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_pair.h
Go to the documentation of this file.
1/// @file bslstl_pair.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_pair.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_PAIR
9#define INCLUDED_BSLSTL_PAIR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_pair bslstl_pair
15/// @brief Provide a simple `struct` with two members that may use allocators.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_pair
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_pair-purpose"> Purpose</a>
25/// * <a href="#bslstl_pair-classes"> Classes </a>
26/// * <a href="#bslstl_pair-description"> Description </a>
27/// * <a href="#bslstl_pair-enhancements-enabled-by-modern-language-standards"> Enhancements Enabled by Modern Language Standards </a>
28/// * <a href="#bslstl_pair-conditional-default-constructor"> Conditional Default Constructor (C++11) </a>
29/// * <a href="#bslstl_pair-usage"> Usage </a>
30///
31/// # Purpose {#bslstl_pair-purpose}
32/// Provide a simple `struct` with two members that may use allocators.
33///
34/// # Classes {#bslstl_pair-classes}
35///
36/// - bsl::pair: pair of values, each of which may use a `bslma::Allocator`
37///
38/// **Canonical header:** bsl_utility.h
39///
40/// # Description {#bslstl_pair-description}
41/// `bsl::pair` is an allocator-aware version of `std::pair`.
42/// The `bsl::pair` class template is instantiated on two types, `T1` and `T2`,
43/// and provides two public data members, `first` and `second` of types `T1` and
44/// `T2`, respectively. Each data member might or might not allocate memory
45/// using `bslma::Allocator`. Its interface is identical to `std::pair` except
46/// that it has constructors that take optional allocator arguments to correctly
47/// construct the member variables. For example, a
48/// `bsl::pair<std::string, int>` has member `first` of type `std::string` and
49/// `second` of type `int`. A client can pass a `bslma::Allocator` pointer to
50/// the pair constructor and the constructor will pass it through to the `first`
51/// member. Similarly, the copy constructor takes an optional
52/// `bslma::Allocator` pointer and copy-constructs the `first` member using that
53/// allocator.
54///
55/// `bsl::pair` is unusual in that its data members, `first` and `second`, are
56/// public. Once constructed, a client program accesses these members directly.
57/// This part of the interface is identical to `std::pair`, for which
58/// `bsl::pair` is intended to be a drop-in replacement.
59///
60/// `bsl::pair` has four constructors: a default constructor that
61/// default-constructs the two data members, a copy constructor that
62/// copy-constructs each data member, a constructor taking two arguments of type
63/// `T1` and `T2`, which are used to copy-construct `first` and `second`
64/// respectively, and a conversion constructor template for converting from a
65/// `bsl::pair` of different types, `PARAM_1` and `PARAM_2`, provided `PARAM_1`
66/// is convertible to `T1` and `PARAM_2` is convertible to `T2`. Each
67/// constructor also has an optional `bslma::Allocator` pointer argument. If
68/// neither `T1` nor `T2` use `bslma::Allocator`, this argument is ignored.
69/// Otherwise, either `first` or `second`, or both, depending on whether each
70/// type uses `bslma::Allocator`, will be passed the `bslma::Allocator*`
71/// argument during construction. Whether or not a type uses `bslma::Allocator`
72/// is determined by querying the `bslma::UsesBslmaAllocator` trait for that
73/// type. This component also defines a full set of equality and relational
74/// operators that can be instantiated if `T1` and `T2` both provide those
75/// operators.
76///
77/// A `bsl::pair` declares a set of associated type traits that are computed
78/// from the type traits of `T1` and `T2`. For each supported type trait, a
79/// given specialization of `bsl::pair` has that trait if and only if *both*
80/// `T1` and `T2` have that trait. Supported traits are:
81/// @code
82/// bslmf::IsBitwiseMoveable
83/// bslmf::IsBitwiseEqualityComparable
84/// bsl::is_trivially_copyable
85/// bsl::is_trivially_default_constructible
86/// @endcode
87/// In addition, a `bsl::pair` specialization has the
88/// `bslma::UsesBslmaAllocator` trait if *either* `T1` or `T2` have that trait,
89/// or both.
90///
91/// ## Enhancements Enabled by Modern Language Standards {#bslstl_pair-enhancements-enabled-by-modern-language-standards}
92///
93///
94/// Language standards after the first (C++98) and its corrigendum (C++03) have
95/// added code C++ language features, type traits as well as requirements that
96/// affect the exact interface `pair` provides. This section describes such
97/// enhancements as they become available.
98///
99/// ### Conditional Default Constructor (C++11) {#bslstl_pair-conditional-default-constructor}
100///
101///
102/// C++11 has introduced type traits, many of which needs compiler backing to be
103/// (automatically implementable) and also introduced "defaulted" (special
104/// member) functions that generate code without making mistakes. Before C++11
105/// it was not possible to determine if a type had a default constructor in a
106/// non-intrusive manner. C++11 makes it possible using <type_traits> to
107/// determine that, and `= default` makes it possible to create special member
108/// functions that exists only when they can be implemented properly.
109///
110/// Hence, when using compilers with a reasonably complete implementation of
111/// C++11 (notably MSVC 2013 is not one of those) we only implement the default
112/// constructor of pair if both types inside the pair type have a default
113/// constructor. Note that it means that when using C++11 (except in compilers
114/// not implementing it properly) a `bsl::pair` that stores a reference type
115/// (such as `int&`), or any other type that cannot be default constructed using
116/// the syntax `T v{};` will cause pair to neither declare nor define a default
117/// constructor. So from C++11 onwards a type of `bsl::pair<T1, T2>` will have
118/// a default constructor only if both types `T1` and `T2` are default
119/// constructible. Otherwise, pair will have a default constructor that gives a
120/// compile-error (only) if called.
121///
122/// ## Usage {#bslstl_pair-usage}
123///
124///
125/// A `bsl::pair` is a very simple object when used without allocators. Our
126/// usage example concentrates on the use of allocators with `bsl::pair`.
127/// First, we create a utility function that copies a null-terminated string
128/// into memory allocated from a supplied allocator:
129/// @code
130/// char *myStrDup(const char *s, bslma::Allocator *basicAllocator)
131/// // Copy the specified null-terminated string 's' into memory allocated
132/// // from the specified 'basicAllocator'
133/// {
134/// char *result = (char*) basicAllocator->allocate(std::strlen(s) + 1);
135/// return std::strcpy(result, s);
136/// }
137/// @endcode
138/// We create a simple string class that holds strings allocated from a supplied
139/// allocator. It uses `myStrDup` (above) in its implementation:
140/// @code
141/// class my_String {
142/// // Simple string class that uses a 'bslma::Allocator' allocator.
143///
144/// bslma::Allocator *d_allocator_p;
145/// char *d_data;
146///
147/// public:
148/// BSLMF_NESTED_TRAIT_DECLARATION(my_String, bslma::UsesBslmaAllocator);
149///
150/// explicit my_String(bslma::Allocator *basicAllocator = 0);
151/// // Construct an empty string using the optionally-specified
152/// // allocator 'basicAllocator'.
153///
154/// my_String(const char* s, bslma::Allocator *alloc = 0); // IMPLICIT
155/// // Construct a string with contents specified in 's' using the
156/// // optionally-specified allocator 'basicAllocator'.
157///
158/// my_String(const my_String& rhs, bslma::Allocator *alloc = 0);
159/// // Construct a copy of the specified 'rhs' string using the
160/// // optionally-specified allocator 'basicAllocator'.
161///
162/// ~my_String();
163/// // Destroy this string.
164///
165/// my_String& operator=(const my_String& rhs);
166/// // Copy specified 'rhs' string value to this string.
167///
168/// const char* c_str() const;
169/// // Return the null-terminated character array for this string.
170///
171/// bslma::Allocator *allocator() const;
172/// // Return the allocator used to construct this string or, if no
173/// // allocator was specified at construction, the default allocator
174/// // at the time of construction.
175/// };
176///
177/// bool operator==(const my_String& str1, const my_String& str2)
178/// {
179/// return 0 == std::strcmp(str1.c_str(), str2.c_str());
180/// }
181///
182/// bool operator==(const my_String& str, const char *p)
183/// {
184/// return 0 == std::strcmp(p, str.c_str());
185/// }
186///
187/// bool operator==(const char *p, const my_String& str)
188/// {
189/// return str == p;
190/// }
191///
192/// bool operator!=(const my_String& str1, const my_String& str2)
193/// {
194/// return ! (str1 == str2);
195/// }
196///
197/// bool operator!=(const my_String& str, const char *p)
198/// {
199/// return ! (str == p);
200/// }
201///
202/// bool operator!=(const char *p, const my_String& str)
203/// {
204/// return ! (str == p);
205/// }
206///
207/// bool operator<(const my_String& str1, const my_String& str2)
208/// {
209/// return std::strcmp(str1.c_str(), str2.c_str()) < 0;
210/// }
211///
212/// my_String::my_String(bslma::Allocator *basicAllocator)
213/// : d_allocator_p(bslma::Default::allocator(basicAllocator)), d_data(0)
214/// {
215/// d_data = myStrDup("", d_allocator_p);
216/// }
217///
218/// my_String::my_String(const char *s, bslma::Allocator *basicAllocator)
219/// : d_allocator_p(bslma::Default::allocator(basicAllocator)), d_data(0)
220/// {
221/// d_data = myStrDup(s, d_allocator_p);
222/// }
223///
224/// my_String::my_String(const my_String& rhs,
225/// bslma::Allocator *basicAllocator)
226/// : d_allocator_p(bslma::Default::allocator(basicAllocator)), d_data(0)
227/// {
228/// d_data = myStrDup(rhs.d_data, d_allocator_p);
229/// }
230///
231/// my_String::~my_String()
232/// {
233/// d_allocator_p->deallocate(d_data);
234/// }
235///
236/// my_String& my_String::operator=(const my_String& rhs)
237/// {
238/// if (this != &rhs) {
239/// d_allocator_p->deallocate(d_data);
240/// d_data = myStrDup(rhs.d_data, d_allocator_p);
241/// }
242/// return *this;
243/// }
244///
245/// const char *my_String::c_str() const
246/// {
247/// return d_data;
248/// }
249///
250/// bslma::Allocator *my_String::allocator() const
251/// {
252/// return d_allocator_p;
253/// }
254/// @endcode
255/// Our main program creates a mapping from strings to integers. Each node of
256/// the mapping consists of a `bsl::pair<my_String, int>`. The program
257/// allocates memory from a test allocator in order to ensure that there are no
258/// leaks:
259/// @code
260/// int main()
261/// {
262/// typedef bsl::pair<my_String, int> Node;
263///
264/// Node *mapping[3];
265/// bslma::TestAllocator alloc;
266/// @endcode
267/// When constructing a `Node`, an allocator is supplied in addition to
268/// parameters for the `first` and `second` data members.
269/// @code
270/// {
271/// mapping[0] = new(basicAllocator) Node("One", 1, &basicAllocator);
272/// mapping[1] = new(basicAllocator) Node("Three", 3, &basicAllocator);
273/// mapping[2] = new(basicAllocator) Node("Two", 2, &basicAllocator);
274/// // Temporaries get destroyed here, even on broken compilers.
275/// }
276///
277/// assert("One" == mapping[0]->first);
278/// assert(1 == mapping[0]->second);
279/// assert("Three" == mapping[1]->first);
280/// assert(3 == mapping[1]->second);
281/// assert("Two" == mapping[2]->first);
282/// assert(2 == mapping[2]->second);
283///
284/// assert(6 == alloc.numBlocksInUse());
285/// @endcode
286/// Clean up at end.
287/// @code
288/// alloc.deleteObjectRaw(mapping[0]);
289/// alloc.deleteObjectRaw(mapping[1]);
290/// alloc.deleteObjectRaw(mapping[2]);
291///
292/// assert(0 == alloc.numBlocksInUse());
293///
294/// return 0;
295/// }
296/// @endcode
297/// @}
298/** @} */
299/** @} */
300
301/** @addtogroup bsl
302 * @{
303 */
304/** @addtogroup bslstl
305 * @{
306 */
307/** @addtogroup bslstl_pair
308 * @{
309 */
310
311#include <bslscm_version.h>
312
313#include <bslstl_hash.h>
314
316
317#include <bslh_hash.h>
318
319#include <bslma_allocator.h>
320
321#ifndef BDE_OMIT_INTERNAL_DEPRECATED
323#endif // BDE_OMIT_INTERNAL_DEPRECATED
325
327#include <bslmf_allocatorargt.h>
328#include <bslmf_conditional.h>
333#include <bslmf_isconvertible.h>
335#include <bslmf_ispair.h>
336#include <bslmf_isswappable.h>
340#include <bslmf_movableref.h>
342#include <bslmf_util.h>
343
345#include <bsls_keyword.h>
346#include <bsls_libraryfeatures.h>
347#include <bsls_platform.h>
348#include <bsls_util.h> // 'forward<T>(V)'
349
350#include <cstddef> // 'std::size_t'
351
352#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE)
353# include <tuple> // 'std::tuple'
354#endif
355
356#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS
357#include <concepts>
358#endif
359
360#include <utility> // 'std::pair' and (in C++11 mode) 'std::swap'
361
362#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
363#include <bsls_nativestd.h>
364#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
365
366#if !defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) \
367 && !defined(BSLS_PLATFORM_CMP_CLANG)
368
369// If the compiler supports rvalue references, then we have C++11 'std::swap',
370// which has a complicated SFINAE clause. Fortunately, it is defined in
371// <utility>, which is included.
372//
373// However, if the compiler does not support rvalue references, then we have
374// C++03 'std::swap', which has a trivial signature. We forward-declare it
375// here because otherwise we'd have to '#include <algorithm>', which causes
376// difficult-to-fix cyclic dependencies between the native library and bsl.
377#ifdef std
378# error This header should not be #included with 'std' being a macro
379#endif
380
381#if !defined(BSLS_PLATFORM_CMP_SUN) \
382 || !defined(BSLS_COMPILERFEATURES_SUPPORT_NOEXCEPT)
383namespace std {
384template <class TYPE>
385void swap(TYPE& a, TYPE& b);
386} // close namespace std
387#endif
388
389#endif // ! BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES && ! CLANG
390
391
392#if !defined(BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS) \
393 || (defined(BSLS_PLATFORM_CMP_MSVC) && BSLS_PLATFORM_CMP_VERSION < 1900)
394# define BSLSTL_PAIR_NO_IMPLICIT_DELETED_FOR_MOVE_OPS 1
395// In order to support the correct signature for copy constructor/assignment
396// operators of members with non-'const' references for those operations, we
397// must take the implicitly generated declarations. However, the specification
398// for assignment through references requires defining the assignment operator
399// in those cases, and that will delete any (otherwise) implicitly-declared
400// constructors, so they must be explicitly defaulted on platforms that support
401// them. However, Visual C++ 2013 refused to recognize these defaults as valid
402// for move constructors, so a special exception must be made in this case.
403#endif
404
405#if !defined(BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS) || \
406 !defined(BSLS_COMPILERFEATURES_SUPPORT_DEFAULT_TEMPLATE_ARGS) || \
407 (defined(BSLS_PLATFORM_CMP_MSVC) && BSLS_PLATFORM_CMP_VERSION < 1900)
408// MSVC 2013 implicitly declared and defines a default constructor, even for
409// members that are not default constructible such as references.
410#define BSLSTL_PAIR_DO_NOT_DEFAULT_THE_DEFAULT_CONSTRUCTOR 1
411#endif
412
413#if defined(BSLS_PLATFORM_CMP_MSVC)
414#if (BSLS_COMPILERFEATURES_CPLUSPLUS < 201703L || \
415 BSLS_PLATFORM_CMP_VERSION <= 1916)
416// MSVC 2017 and earlier, as well as later versions of MSVC compiling against
417// pre-C++17 standards, are unable to perform the required template argument
418// deductions to enable the use of 'bsl::is_swappable' within the SFINAE test
419// for 'swap()'. In this case we must fall back on the previous, pre-C++17
420// implementation which simply assumes swappability.
421#define BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE 1
422#endif
423#endif
424
425#if !defined(BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE)
426// When compiling without 'decltype' support, 'bsl::is_swappable' is not
427// defined. In this case we must fall back on the previous, pre-C++17
428// implementation which simply assumes swappability.
429#define BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE 1
430#endif
431
432
433namespace bslstl {
434
435#ifdef BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE
436/// `Pair_IndexSequence` is an alias to the `bslmf::IntegerSequence` class
437/// template specialized for the common case of the integer sequence were
438/// the element type `T` is `std::size_t`.
439template <std::size_t... INTS>
440using Pair_IndexSequence = bslmf::IntegerSequence<std::size_t, INTS...>;
441
442
443/// `Pair_MakeIndexSequence` is an alias template to the
444/// `bslmf::MakeIntegerSequence` meta-function specialized for the common
445/// case of the integer sequence were the element type `T` is `std::size_t`.
446template <std::size_t N>
447using Pair_MakeIndexSequence = bslmf::MakeIntegerSequence<std::size_t, N>;
448#endif
449
450} // close package namespace
451
452
453namespace bsl {
454 // =========================
455 // trait Pair_AllocatorIdiom
456 // =========================
457
458/// Type tag for types that do not take a `bslma::Allocator*` constructor
459/// argument.
461
462/// Type tag for types that take a `bslma::Allocator*` as the last argument
463/// of their constructors.
465
466/// Type tag for types that take a `bslma::Allocator*` as the second
467/// argument of their constructors, following an argument of type
468/// `bsl::allocator_arg_t`.
470
471/// This component-private meta-function determines whether the specified
472/// `TYPE` template parameter takes a `bslma::Allocator*` constructor
473/// argument and, if so, whether that argument is at the end of the argument
474/// list or at the beginning of the argument list following an argument of
475/// type `bsl::allocator_arg_t`. This type derived from
476/// `bsl::integral_constant<int, N>` where `N` is the number of additional
477/// parameters required to pass an allocator to a constructor using the
478/// chosen idiom.
479template <class TYPE>
481 BloombergLP::bslma::UsesBslmaAllocator<TYPE>::value
482 ? (BloombergLP::bslmf::UsesAllocatorArgT<TYPE>::value
483 ? Pair_BslmaIdiomAllocatorArgT::value
484 : Pair_BslmaIdiomAtEnd::value)
485 : Pair_BslmaIdiomNone::value>
486{
487};
488
489#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE)
490/// This component-private component-private meta-function determines the
491/// number of elements in a tuple containing parameters for piecewise
492/// construction of a `bsl::pair` member having the specified `TYPE`.
493/// Result value depends on the `TYPE`, whether it takes a
494/// `bslma::Allocator*` constructor argument and, if so, whether that
495/// argument follows an argument of type `bsl::allocator_arg_t`.
496template <class TYPE, class ... ARGS>
497struct Pair_ConstructionParametersPackLength : integral_constant<int,
498 sizeof...(ARGS) + Pair_BslmaIdiom<TYPE>::value >
499{
500};
501#endif
502
503 // ===================
504 // struct Pair_ImpUtil
505 // ===================
507 // This 'struct' provides a namespace for utility functions used to
508 // creating a tuple, containing arguments for the constructor of pair
509 // element in the process of 'bsl::pair' piecewise construction.
510
511 // CLASS METHODS
512#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE)
513 /// Construct and return by value a tuple, containing arguments for the
514 /// corresponding constructor of (template parameter) `TYPE`,
515 /// forwarding in order the elements in the specified `tpl` and
516 /// discarding the specified `alloc`, because `TYPE` does not support
517 /// `bslma`-style allocators. This method provides the no-throw
518 /// exception-safety guarantee.
519 template <class ... ARGS>
520 static
521 std::tuple<ARGS...>
522 concatAllocator(
523 BSLS_COMPILERFEATURES_FORWARD_REF(std::tuple<ARGS...>) tpl,
524 BloombergLP::bslma::Allocator *alloc,
526
527
528 /// Construct and return by value a tuple, containing arguments for the
529 /// corresponding constructor of (template parameter) `TYPE`,
530 /// forwarding in order the elements in the specified `tpl` and
531 /// appending the specified `alloc`, because `TYPE` takes a
532 /// `bslma`-style allocator as the last constructor argument. This
533 /// method provides the no-throw exception-safety guarantee.
534 template <class ... ARGS>
535 static
536 std::tuple<ARGS..., BloombergLP::bslma::Allocator *>
537 concatAllocator(
538 BSLS_COMPILERFEATURES_FORWARD_REF(std::tuple<ARGS...>) tpl,
539 BloombergLP::bslma::Allocator *alloc,
541
542 /// Construct and return by value a tuple, containing arguments for the
543 /// corresponding constructor of (template parameter) `TYPE`, forwarding
544 /// in order the elements in the specified `tpl` preceded by
545 /// `bsl::allocator_arg` object and the specified `alloc`, because
546 /// `TYPE` takes a `bslma`-style allocator as the second constructor
547 /// argument preceded by `bsl::allocator_arg`. This method provides the
548 /// no-throw exception-safety guarantee.
549 template <class ... ARGS>
550 static
551 std::tuple<bsl::allocator_arg_t,
552 BloombergLP::bslma::Allocator *,
553 ARGS...>
554 concatAllocator(
555 BSLS_COMPILERFEATURES_FORWARD_REF(std::tuple<ARGS...>) tpl,
556 BloombergLP::bslma::Allocator *alloc,
558#endif
559
560#if defined(BSLS_COMPILERFEATURES_SUPPORT_NOEXCEPT) && \
561 defined(BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE)
562 template <class TYPE1, class TYPE2>
563 static constexpr bool hasNothrowSwap()
564 // Utility function to determine whether 'swap()' is 'noexcept (true)'
565 // when called with the specified (template) arguments 'TYPE1' and
566 // 'TYPE2'. This function is only defined on platforms where
567 // 'noexcept' is supported but the newer, C++17 compatible trait
568 // 'bsl::is_nothrow_swappable' is not available.
569 {
570 using std::swap;
571 typedef BloombergLP::bslmf::Util U;
572 return BSLS_KEYWORD_NOEXCEPT_OPERATOR(swap(U::declval<TYPE1&>(),
573 U::declval<TYPE1&>())) &&
574 BSLS_KEYWORD_NOEXCEPT_OPERATOR(swap(U::declval<TYPE2&>(),
575 U::declval<TYPE2&>()));
576 }
577#endif
578};
579
580 // =================
581 // struct Pair_First
582 // =================
583
584/// This component-private `class` holds the `first` data member of a `pair`
585/// and constructs it appropriately.
586template <class TYPE>
588
589 private:
590 // PRIVATE TYPES
591
592 /// This typedef is a convenient alias for the utility associated with
593 /// implementing movable references in C++03 and C++11 environments.
594 typedef BloombergLP::bslmf::MovableRefUtil MovUtil;
595
597
598 /// This empty `struct` is used with `bsl::enable_if` in template
599 /// constraints.
600 struct SfinaeEnable {};
601
602 protected:
603 public:
604 // PUBLIC DATA
605 TYPE first;
606
607 // CREATORS
608#if !defined(BSLSTL_PAIR_DO_NOT_DEFAULT_THE_DEFAULT_CONSTRUCTOR)
609 template <
610 class BSLSTL_DUMMY = TYPE,
611 typename
612 std::enable_if<std::is_default_constructible<BSLSTL_DUMMY>::value,
613 int>::type = 0>
615 Pair_First() : first()
616 {
617 // This constructor template must be defined inline inside the
618 // class definition, as Microsoft Visual C++ does not recognize the
619 // definition as matching this signature when placed out-of-line.
620 }
621#else
624#endif
625 // Construct the 'first' member of a 'pair' using the default
626 // constructor for (template parameter) 'TYPE'.
627
628 Pair_First(BloombergLP::bslma::Allocator *basicAllocator,
630 Pair_First(BloombergLP::bslma::Allocator *basicAllocator,
632 /// Construct the `first` member of a `pair`, using the specified
633 /// `basicAllocator` to supply memory. Note that exactly one of these
634 /// three constructors is enabled at compile-time for (template
635 /// parameter) type `TYPE` based on the following respective criteria:
636 /// 1) `TYPE` does not support `bslma`-style allocators, 2) `TYPE`
637 /// takes a `bslma`-style allocator as the last constructor argument,
638 /// and 3) `TYPE` takes a `bslma`-style allocator as the second
639 /// constructor argument preceded by `bsl::allocator_arg`.
640 Pair_First(BloombergLP::bslma::Allocator *basicAllocator,
642
643 /// Construct the `first` member from the specified non-modifiable
644 /// `value`, without specifying an allocator.
646 explicit Pair_First(
648
649#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
650 template <class PARAM>
652 PARAM&& value,
653 typename std::enable_if<
654 !std::is_same<
656 typename std::remove_cv<
657 typename std::remove_reference<PARAM>::type>::type>::value,
658 SfinaeEnable>::type = SfinaeEnable());
659#else
660 template <class PARAM>
662 explicit Pair_First(const PARAM& value);
663 template <class PARAM>
665 explicit Pair_First(PARAM& value);
666#endif
667 // TBD: improve comment.
668 // Construct the 'first' member from the specified 'value', without
669 // specifying an allocator. This function (perfectly) forwards 'value'
670 // to the constructor of (template parameter) 'TYPE'.
671
672#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
673 template <class PARAM>
674 Pair_First(PARAM&& value,
675 BloombergLP::bslma::Allocator *basicAllocator,
677 template <class PARAM>
678 Pair_First(PARAM&& value,
679 BloombergLP::bslma::Allocator *basicAllocator,
681 template <class PARAM>
682 Pair_First(PARAM&& value,
683 BloombergLP::bslma::Allocator *basicAllocator,
685#else
686 template <class PARAM>
687 Pair_First(const PARAM& value,
688 BloombergLP::bslma::Allocator *basicAllocator,
690 template <class PARAM>
691 Pair_First(PARAM& value,
692 BloombergLP::bslma::Allocator *basicAllocator,
694 template <class PARAM>
695 Pair_First(const PARAM& value,
696 BloombergLP::bslma::Allocator *basicAllocator,
698 template <class PARAM>
699 Pair_First(PARAM& value,
700 BloombergLP::bslma::Allocator *basicAllocator,
702 template <class PARAM>
703 Pair_First(const PARAM& value,
704 BloombergLP::bslma::Allocator *basicAllocator,
706 template <class PARAM>
707 Pair_First(PARAM& value,
708 BloombergLP::bslma::Allocator *basicAllocator,
710#endif
711 // Construct the 'first' member of a 'pair' from the specified 'value',
712 // using the specified 'basicAllocator' to supply memory. This
713 // function (perfectly) forwards 'value' to the constructor of
714 // (template parameter) 'TYPE'. Note that exactly one of these three
715 // constructors is enabled at compile-time for (template parameter)
716 // type 'TYPE' based on the following respective criteria: 1) 'TYPE'
717 // does not support 'bslma'-style allocators, 2) 'TYPE' takes a
718 // 'bslma'-style allocator as the last constructor argument, and 3)
719 // 'TYPE' takes a 'bslma'-style allocator as the second constructor
720 // argument preceded by 'bsl::allocator_arg'.
721
722#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \
723 && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE)
724 /// Construct the `first` member of a `pair`, forwarding in order the
725 /// elements in the specified `argsPack` to the corresponding
726 /// constructor of (template parameter) `TYPE`. The length of the
727 /// `argsPack` is equal to the lenght of the specified (template
728 /// parameter pack) `I...` and passed to the constructor via the
729 /// `Pair_IndexSequence` object.
730 template <class ...ARGS, size_t ...I>
731 Pair_First(std::tuple<ARGS...>&& argsPack,
732 BloombergLP::bslstl::Pair_IndexSequence<I...>);
733#endif
734
735 Pair_First(const Pair_First&) = default;
736 Pair_First(Pair_First&&) = default;
738 ~Pair_First() = default;
739};
740
741/// This component-private `class` holds the `first` data member of a `pair`
742/// and constructs it appropriately.
743template <class TYPE>
744struct Pair_First<TYPE&> {
745
746 protected:
747 // PROTECTED DATA
748 TYPE& first;
749
750 // CREATORS
751
752 /// Bind the specified `value` into the `first` reference-member.
754 explicit Pair_First(TYPE& value);
755
756#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
757 template <class PARAM>
759 explicit Pair_First(PARAM&& value);
760#else
761 template <class PARAM>
763 explicit Pair_First(const PARAM& value); // for derived-to-const-base-ref
764 template <class PARAM>
766 explicit Pair_First(PARAM& value);
767#endif
768 // Bind the specified 'value' into the 'first' reference-member.
769 // TBD: Consider SFINAE-ing these constructors
770
771#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
772 template <class PARAM>
774 Pair_First(PARAM&& value,
775 BloombergLP::bslma::Allocator *basicAllocator,
777#else
778 template <class PARAM>
780 Pair_First(const PARAM& value,
781 BloombergLP::bslma::Allocator *basicAllocator,
783 template <class PARAM>
785 Pair_First(PARAM& value,
786 BloombergLP::bslma::Allocator *basicAllocator,
788#endif
789 // Bind the specified 'value' into the 'first' reference-member. The
790 // specified 'basicAllocator' is not used.
791
792#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \
793 && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE)
794 /// Construct the `first` member of a `pair`, forwarding in order the
795 /// elements in the specified `argsPack` to the corresponding
796 /// constructor of (template parameter) `TYPE`. The length of the
797 /// `argsPack` is equal to the lenght of the specified (template
798 /// parameter pack) `I...` and passed to the constructor via the
799 /// `Pair_IndexSequence` object.
800 template <class ARG>
802 Pair_First(std::tuple<ARG>&& arg,
803 BloombergLP::bslstl::Pair_IndexSequence<0u>);
804#endif
805
806 ~Pair_First() = default;
807
808 // MANIPULATORS
809#if !defined(BSLSTL_PAIR_NO_IMPLICIT_DELETED_FOR_MOVE_OPS)
810 Pair_First(const Pair_First&) = default;
811 Pair_First(Pair_First&&) = default;
812#endif
813 Pair_First& operator=(const Pair_First& rhs) BSLS_KEYWORD_NOEXCEPT;
814};
815
816#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
817/// This component-private `class` holds the `first` data member of a `pair`
818/// and constructs it appropriately.
819template <class TYPE>
820struct Pair_First<TYPE&&> {
821
822 protected:
823 // PROTECTED DATA
824 TYPE&& first;
825
826 // CREATORS
827
828 /// Construct the `first` member from the specified non-modifiable
829 /// `value`, without specifying an allocator.
831 explicit Pair_First(TYPE&& value);
832
833 /// TBD: improve comment.
834 /// Construct the `first` member from the specified `value`, without
835 /// specifying an allocator. This function (perfectly) forwards `value`
836 /// to the constructor of (template parameter) `TYPE`.
837 /// TBD: Consider SFINAE-ing this constructor, but maybe better handled
838 /// at the `pair` level?
839 template <class PARAM>
841 explicit Pair_First(PARAM&& value);
842
843 /// Construct the `first` member of a `pair` from the specified `value`,
844 /// using the specified `basicAllocator` to supply memory. This
845 /// function (perfectly) forwards `value` to the constructor of
846 /// (template parameter) `TYPE`. Note that exactly one of these three
847 /// constructors is enabled at compile-time for (template parameter)
848 /// type `TYPE` based on the following respective criteria: 1) `TYPE`
849 /// does not support `bslma`-style allocators, 2) `TYPE` takes a
850 /// `bslma`-style allocator as the last constructor argument, and 3)
851 /// `TYPE` takes a `bslma`-style allocator as the second constructor
852 /// argument preceded by `bsl::allocator_arg`.
853 template <class PARAM>
855 Pair_First(PARAM&& value,
856 BloombergLP::bslma::Allocator *basicAllocator,
858
859#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \
860 && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE)
861 /// Construct the `first` member of a `pair`, forwarding in order the
862 /// elements in the specified `argsPack` to the corresponding
863 /// constructor of (template parameter) `TYPE`. The length of the
864 /// `argsPack` is equal to the lenght of the specified (template
865 /// parameter pack) `I...` and passed to the constructor via the
866 /// `Pair_IndexSequence` object.
867 template <class ARG>
869 Pair_First(std::tuple<ARG>&& arg,
870 BloombergLP::bslstl::Pair_IndexSequence<0u>);
871#endif
872
873 ~Pair_First() = default;
874
875 // MANIPULATORS
876#if !defined(BSLSTL_PAIR_NO_IMPLICIT_DELETED_FOR_MOVE_OPS)
877 Pair_First(const Pair_First&) = default;
878 Pair_First(Pair_First&&) = default;
879#endif
880 Pair_First& operator=(const Pair_First& rhs) BSLS_KEYWORD_NOEXCEPT;
881};
882#endif
883
884 // ==================
885 // struct Pair_Second
886 // ==================
887
888/// This component-private `class` holds the `second` data member of a
889/// `pair` and constructs it appropriately.
890template <class TYPE>
892
893 private:
894 // PRIVATE TYPES
895
896 /// This typedef is a convenient alias for the utility associated with
897 /// implementing movable references in C++03 and C++11 environments.
898 typedef BloombergLP::bslmf::MovableRefUtil MovUtil;
899
901
902 /// This empty `struct` is used with `bsl::enable_if` in template
903 /// constraints.
904 struct SfinaeEnable {};
905
906 protected:
907 // PROTECTED DATA
908 TYPE second;
909
910 // CREATORS
911#if !defined(BSLSTL_PAIR_DO_NOT_DEFAULT_THE_DEFAULT_CONSTRUCTOR)
912 template <
913 class BSLSTL_DUMMY = TYPE,
914 typename
915 std::enable_if<std::is_default_constructible<BSLSTL_DUMMY>::value,
916 int>::type = 0>
918 Pair_Second() : second()
919 {
920 // This constructor template must be defined inline inside the
921 // class definition, as Microsoft Visual C++ does not recognize the
922 // definition as matching this signature when placed out-of-line.
923 }
924#else
927#endif
928 // Construct the 'second' member of a 'pair' using the default
929 // constructor for (template parameter) type 'TYPE'.
930
931 Pair_Second(BloombergLP::bslma::Allocator *basicAllocator,
933 Pair_Second(BloombergLP::bslma::Allocator *basicAllocator,
935 /// Construct the `second` member of a `pair`, using the specified
936 /// `basicAllocator` to supply memory. Note that exactly one of these
937 /// three constructors is enabled at compile-time for (template
938 /// parameter) type `TYPE` based on the following respective criteria:
939 /// 1) `TYPE` does not support `bslma`-style allocators, 2) `TYPE`
940 /// takes a `bslma`-style allocator as the last constructor argument,
941 /// and 3) `TYPE` takes a `bslma`-style allocator as the second
942 /// constructor argument preceded by `bsl::allocator_arg`.
943 Pair_Second(BloombergLP::bslma::Allocator *basicAllocator,
945
946 /// Construct the `second` member from the specified non-modifiable
947 /// `value`, without specifying an allocator.
949 explicit Pair_Second(
951
952#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
953 template <class PARAM>
955 PARAM&& value,
956 typename std::enable_if<
957 !std::is_same<
959 typename std::remove_cv<
960 typename std::remove_reference<PARAM>::type>::type>::value,
961 SfinaeEnable>::type = SfinaeEnable());
962#else
963 template <class PARAM>
965 explicit Pair_Second(const PARAM& value);
966 template <class PARAM>
968 explicit Pair_Second(PARAM& value);
969#endif
970 // Construct the 'second' member from the specified 'value', without
971 // specifying an allocator. This function (perfectly) forwards 'value'
972 // to the constructor of (template parameter) 'TYPE'.
973
974#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
975 template <class PARAM>
976 Pair_Second(PARAM&& value,
977 BloombergLP::bslma::Allocator *basicAllocator,
979 template <class PARAM>
980 Pair_Second(PARAM&& value,
981 BloombergLP::bslma::Allocator *basicAllocator,
983 template <class PARAM>
984 Pair_Second(PARAM&& value,
985 BloombergLP::bslma::Allocator *basicAllocator,
987#else
988 template <class PARAM>
989 Pair_Second(const PARAM& value,
990 BloombergLP::bslma::Allocator *basicAllocator,
992 template <class PARAM>
993 Pair_Second(PARAM& value,
994 BloombergLP::bslma::Allocator *basicAllocator,
996 template <class PARAM>
997 Pair_Second(const PARAM& value,
998 BloombergLP::bslma::Allocator *basicAllocator,
1000 template <class PARAM>
1001 Pair_Second(PARAM& value,
1002 BloombergLP::bslma::Allocator *basicAllocator,
1004 template <class PARAM>
1005 Pair_Second(const PARAM& value,
1006 BloombergLP::bslma::Allocator *basicAllocator,
1008 template <class PARAM>
1009 Pair_Second(PARAM& value,
1010 BloombergLP::bslma::Allocator *basicAllocator,
1012#endif
1013 // Construct the 'second' member of a 'pair' from the specified
1014 // forwarding reference 'value', using the specified 'basicAllocator'
1015 // to supply memory. This function (perfectly) forwards 'value' to the
1016 // constructor of (template parameter) 'TYPE'. Note that exactly one
1017 // of these three constructors is enabled at compile-time for (template
1018 // parameter) type 'TYPE' based on the following respective criteria:
1019 // 1) 'TYPE' does not support 'bslma'-style allocators, 2) 'TYPE' takes
1020 // a 'bslma'-style allocator as the last constructor argument, and 3)
1021 // 'TYPE' takes a 'bslma'-style allocator as the second constructor
1022 // argument preceded by 'bsl::allocator_arg'.
1023
1024#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \
1025 && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE)
1026 /// Construct the `second` member of a `pair`, forwarding in order the
1027 /// elements in the specified `argsPack` to the corresponding
1028 /// constructor of (template parameter) `TYPE`. The length of the
1029 /// `argsPack` is equal to the lenght of the specified (template
1030 /// parameter pack) `I...` and passed to the constructor via the
1031 /// `Pair_IndexSequence` object.
1032 template <class ...ARGS, size_t ...I>
1033 Pair_Second(std::tuple<ARGS...>&& argsPack,
1034 BloombergLP::bslstl::Pair_IndexSequence<I...>);
1035#endif
1036
1037 Pair_Second(const Pair_Second&) = default;
1040 ~Pair_Second() = default;
1041};
1042
1043/// This component-private `class` holds the `second` data member of a
1044/// `pair` and constructs it appropriately.
1045template <class TYPE>
1046struct Pair_Second<TYPE&> {
1047
1048 protected:
1049 // PUBLIC DATA
1050 TYPE& second;
1051
1052 // CREATORS
1053
1054 /// Construct the `second` member from the specified non-modifiable
1055 /// `value`, without specifying an allocator.
1057 explicit Pair_Second(TYPE& value);
1058
1059#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
1060 template <class PARAM>
1062 explicit Pair_Second(PARAM&& value);
1063#else
1064 template <class PARAM>
1066 explicit Pair_Second(const PARAM& value);
1067 template <class PARAM>
1069 explicit Pair_Second(PARAM& value);
1070#endif
1071 // Construct the 'second' member from the specified 'value', without
1072 // specifying an allocator. This function (perfectly) forwards 'value'
1073 // to the constructor of (template parameter) 'TYPE'.
1074
1075#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
1076 template <class PARAM>
1078 Pair_Second(PARAM&& value,
1079 BloombergLP::bslma::Allocator *basicAllocator,
1081#else
1082 template <class PARAM>
1084 Pair_Second(const PARAM& value,
1085 BloombergLP::bslma::Allocator *basicAllocator,
1087 template <class PARAM>
1089 Pair_Second(PARAM& value,
1090 BloombergLP::bslma::Allocator *basicAllocator,
1092#endif
1093 // Construct the 'second' member of a 'pair' from the specified
1094 // forwarding reference 'value', using the specified 'basicAllocator'
1095 // to supply memory. This function (perfectly) forwards 'value' to the
1096 // constructor of (template parameter) 'TYPE'. Note that exactly one
1097 // of these three constructors is enabled at compile-time for (template
1098 // parameter) type 'TYPE' based on the following respective criteria:
1099 // 1) 'TYPE' does not support 'bslma'-style allocators, 2) 'TYPE' takes
1100 // a 'bslma'-style allocator as the last constructor argument, and 3)
1101 // 'TYPE' takes a 'bslma'-style allocator as the second constructor
1102 // argument preceded by 'bsl::allocator_arg'.
1103
1104#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \
1105 && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE)
1106 /// Construct the `second` member of a `pair`, forwarding in order the
1107 /// elements in the specified `argsPack` to the corresponding
1108 /// constructor of (template parameter) `TYPE`. The length of the
1109 /// `argsPack` is equal to the lenght of the specified (template
1110 /// parameter pack) `I...` and passed to the constructor via the
1111 /// `Pair_IndexSequence` object.
1112 template <class ARG>
1114 Pair_Second(std::tuple<ARG>&& arg,
1115 BloombergLP::bslstl::Pair_IndexSequence<0u>);
1116#endif
1117
1118 ~Pair_Second() = default;
1119
1120 // MANIPULATORS
1121#if !defined(BSLSTL_PAIR_NO_IMPLICIT_DELETED_FOR_MOVE_OPS)
1122 Pair_Second(const Pair_Second&) = default;
1123 Pair_Second(Pair_Second&&) = default;
1124#endif
1125 Pair_Second& operator=(const Pair_Second& rhs) BSLS_KEYWORD_NOEXCEPT;
1126};
1127
1128#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
1129/// This component-private `class` holds the `second` data member of a
1130/// `pair` and constructs it appropriately.
1131template <class TYPE>
1132struct Pair_Second<TYPE&&> {
1133
1134 protected:
1135 // PROTECTED DATA
1136 TYPE&& second;
1137
1138 // CREATORS
1139
1140 /// Construct the `second` member from the specified non-modifiable
1141 /// `value`, without specifying an allocator.
1143 explicit Pair_Second(TYPE&& value);
1144
1145 /// Construct the `second` member from the specified `value`, without
1146 /// specifying an allocator. This function (perfectly) forwards `value`
1147 /// to the constructor of (template parameter) `TYPE`.
1148 template <class PARAM>
1150 explicit Pair_Second(PARAM&& value);
1151
1152 /// Construct the `second` member of a `pair` from the specified
1153 /// forwarding reference `value`, using the specified `basicAllocator`
1154 /// to supply memory. This function (perfectly) forwards `value` to the
1155 /// constructor of (template parameter) `TYPE`. Note that exactly one
1156 /// of these three constructors is enabled at compile-time for (template
1157 /// parameter) type `TYPE` based on the following respective criteria:
1158 /// 1) `TYPE` does not support `bslma`-style allocators, 2) `TYPE` takes
1159 /// a `bslma`-style allocator as the last constructor argument, and 3)
1160 /// `TYPE` takes a `bslma`-style allocator as the second constructor
1161 /// argument preceded by `bsl::allocator_arg`.
1162 template <class PARAM>
1164 Pair_Second(PARAM&& value,
1165 BloombergLP::bslma::Allocator *basicAllocator,
1167
1168#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \
1169 && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE)
1170 /// Construct the `second` member of a `pair`, forwarding in order the
1171 /// elements in the specified `argsPack` to the corresponding
1172 /// constructor of (template parameter) `TYPE`. The length of the
1173 /// `argsPack` is equal to the lenght of the specified (template
1174 /// parameter pack) `I...` and passed to the constructor via the
1175 /// `Pair_IndexSequence` object.
1176 template <class ARG>
1178 Pair_Second(std::tuple<ARG>&& arg,
1179 BloombergLP::bslstl::Pair_IndexSequence<0u>);
1180#endif
1181
1182 ~Pair_Second() = default;
1183
1184 // MANIPULATORS
1185#if !defined(BSLSTL_PAIR_NO_IMPLICIT_DELETED_FOR_MOVE_OPS)
1186 Pair_Second(const Pair_Second&) = default;
1187 Pair_Second(Pair_Second&&) = default;
1188#endif
1189 Pair_Second& operator=(const Pair_Second& rhs) BSLS_KEYWORD_NOEXCEPT;
1190};
1191#endif
1192
1193 // ==========
1194 // class pair
1195 // ==========
1196
1197/// The class template `pair` provides a pair of public data members,
1198/// `first` and `second`, of type `T1` and `T2` respectively. If either
1199/// `T1` or `T2` uses `bslma::Allocator` for memory management, then provide
1200/// an optional `bslma::Allocator` argument for each constructor, to be
1201/// passed through to the constructors of `first` and/or `second` as
1202/// appropriate. The interface to this class is identical to the standard
1203/// `std::pair` except for the addition of the allocators. Note that the
1204/// implementation of this class provides `first` and `second` through
1205/// multiple base classes in order to simplify construction of each member
1206/// when allowing for the various rules for passing allocators in C++11.
1207///
1208/// See @ref bslstl_pair
1209template <class T1, class T2>
1210class pair : public Pair_First<T1>, public Pair_Second<T2> {
1211
1212 // PRIVATE TYPES
1213 typedef Pair_First<T1> FirstBase;
1214
1215 /// `ThirdBase` and `HomePlate` left as an exercise for the reader.
1217
1220
1221 /// This typedef is a convenient alias for the utility associated with
1222 /// movable references.
1223 typedef BloombergLP::bslmf::MovableRefUtil MovUtil;
1224
1225 /// This empty `struct` is used with `bsl::enable_if` in template
1226 /// constraints.
1227 struct SfinaeEnable {};
1228
1229 public:
1230 // PUBLIC TYPES
1231 typedef T1 first_type;
1232 typedef T2 second_type;
1233
1234 // PUBLIC DATA
1235 using FirstBase::first;
1236 using SecondBase::second;
1237
1238 // CREATORS
1239#if !defined(BSLSTL_PAIR_DO_NOT_DEFAULT_THE_DEFAULT_CONSTRUCTOR)
1241 pair() = default;
1242#else
1245#endif
1246 /// Construct a `pair` with the `first` and `second` members initialized
1247 /// to default values. Optionally specify a `basicAllocator`, used to
1248 /// supply memory for each of `first` and `second` when its type
1249 /// (template parameter `T1` or `T2`, respectively) uses `bslma`-style
1250 /// allocators. This method requires that `T1` and `T2` be
1251 /// default-constructible.
1252 explicit pair(BloombergLP::bslma::Allocator *basicAllocator);
1253
1254 /// Construct a `pair` having the same value as that of the specified
1255 /// `original` pair. Optionally specify a `basicAllocator`, used to
1256 /// supply memory for each of `first` and `second` when its type
1257 /// (template parameter `T1` or `T2`, respectively) uses `bslma`-style
1258 /// allocators. Note that the copy constructor is implicitly declared
1259 /// (if `T1` and `T2` are both `copy-constructible`) by compilers that
1260 /// do not support defaulted declarations.
1261 pair(const pair& original, BloombergLP::bslma::Allocator *basicAllocator);
1262
1263#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
1264 pair(pair&& original); // Allow move ctor to implicitly default/delete
1265 pair(pair&& original, BloombergLP::bslma::Allocator *basicAllocator);
1266#else
1268 pair(BloombergLP::bslmf::MovableRef<pair> original);
1269 /// Construct a pair having the same value as that of the specified
1270 /// `original` before the call to the move constructor. Optionally
1271 /// specify a `basicAllocator`, used to supply memory for each of
1272 /// `first` and `second` when its type (template parameter `T1` or `T2`,
1273 /// respectively) uses `bslma`-style allocators. Note that `original`
1274 /// is left in a valid but unspecified state. Also note that this
1275 /// method requires that `T1` and `T2` be move-constructible. Note that
1276 /// the move constructor is implicitly declared (if `T1` and `T2` are
1277 /// both move-constructible) by compilers that do not support defaulted
1278 /// declarations, but do support rvalue references.
1279 pair(BloombergLP::bslmf::MovableRef<pair> original,
1280 BloombergLP::bslma::Allocator *basicAllocator);
1281#endif
1282
1286 /// Construct a `pair` with the `first` member initialized to the
1287 /// specified `a` value and the `second` member initialized to the
1288 /// specified `b` value. Optionally specify a `basicAllocator`, used to
1289 /// supply memory for each of `first` and `second` when its type
1290 /// (template parameter `T1` or `T2`, respectively) uses `bslma`-style
1291 /// allocators. This method requires that `T1` and `T2` be
1292 /// `copy-constructible`.
1295 BloombergLP::bslma::Allocator *basicAllocator);
1296
1297#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
1298 template <class PARAM_1, class PARAM_2>
1300 PARAM_1&& a,
1301 PARAM_2&& b,
1302 typename bsl::enable_if<
1303 std::is_constructible<T1, PARAM_1>::value &&
1304 std::is_constructible<T2, PARAM_2>::value &&
1306 typename bsl::remove_reference<PARAM_2>::type>::value &&
1307 bsl::is_convertible<PARAM_2,
1308 BloombergLP::bslma::Allocator *>::value),
1309 SfinaeEnable>::type = SfinaeEnable())
1310 : FirstBase(std::forward<PARAM_1>(a))
1311 , SecondBase(std::forward<PARAM_2>(b))
1312 {
1313 // The implementation is placed here in the class definition to work
1314 // around a Microsoft C++ compiler (MSVC 2010) bug where the definition
1315 // cannot be matched to the declaration when an 'enable_if' is used.
1316 }
1317 template <class PARAM_1, class PARAM_2>
1318 pair(PARAM_1&& a,
1319 PARAM_2&& b,
1320 BloombergLP::bslma::Allocator *basicAllocator);
1321#else
1322 template <class PARAM_1, class PARAM_2>
1324 const PARAM_1& a,
1325 const PARAM_2& b,
1326 typename bsl::enable_if<
1330 typename bsl::remove_reference<PARAM_2>::type>::value &&
1331 bsl::is_convertible<PARAM_2,
1332 BloombergLP::bslma::Allocator *>::value),
1333 SfinaeEnable>::type = SfinaeEnable())
1334 : FirstBase(a)
1335 , SecondBase(b)
1336 {
1337 // The implementation is placed here in the class definition to work
1338 // around a Microsoft C++ compiler (MSVC 2010) bug where the definition
1339 // cannot be matched to the declaration when an 'enable_if' is used.
1340 }
1341 template <class PARAM_1, class PARAM_2>
1342 pair(const PARAM_1& a,
1343 const PARAM_2& b,
1344 BloombergLP::bslma::Allocator *basicAllocator);
1345
1346 template <class PARAM_1, class PARAM_2>
1348 PARAM_1& a,
1349 const PARAM_2& b,
1350 typename bsl::enable_if<
1354 typename bsl::remove_reference<PARAM_2>::type>::value &&
1355 bsl::is_convertible<PARAM_2,
1356 BloombergLP::bslma::Allocator *>::value),
1357 SfinaeEnable>::type = SfinaeEnable())
1358 : FirstBase(a)
1359 , SecondBase(b)
1360 {
1361 // The implementation is placed here in the class definition to work
1362 // around a Microsoft C++ compiler (MSVC 2010) bug where the definition
1363 // cannot be matched to the declaration when an 'enable_if' is used.
1364 }
1365 template <class PARAM_1, class PARAM_2>
1366 pair(PARAM_1& a,
1367 const PARAM_2& b,
1368 BloombergLP::bslma::Allocator *basicAllocator);
1369
1370 template <class PARAM_1, class PARAM_2>
1372 const PARAM_1& a,
1373 PARAM_2& b,
1374 typename bsl::enable_if<
1378 typename bsl::remove_reference<PARAM_2>::type>::value &&
1379 bsl::is_convertible<PARAM_2,
1380 BloombergLP::bslma::Allocator *>::value),
1381 SfinaeEnable>::type = SfinaeEnable())
1382 : FirstBase(a)
1383 , SecondBase(b)
1384 {
1385 // The implementation is placed here in the class definition to work
1386 // around a Microsoft C++ compiler (MSVC 2010) bug where the definition
1387 // cannot be matched to the declaration when an 'enable_if' is used.
1388 }
1389 template <class PARAM_1, class PARAM_2>
1390 pair(const PARAM_1& a,
1391 PARAM_2& b,
1392 BloombergLP::bslma::Allocator *basicAllocator);
1393
1394 template <class PARAM_1, class PARAM_2>
1396 PARAM_1& a,
1397 PARAM_2& b,
1398 typename bsl::enable_if<
1402 typename bsl::remove_reference<PARAM_2>::type>::value &&
1403 bsl::is_convertible<PARAM_2,
1404 BloombergLP::bslma::Allocator *>::value),
1405 SfinaeEnable>::type = SfinaeEnable())
1406 : FirstBase(a)
1407 , SecondBase(b)
1408 {
1409 // The implementation is placed here in the class definition to work
1410 // around a Microsoft C++ compiler (MSVC 2010) bug where the definition
1411 // cannot be matched to the declaration when an 'enable_if' is used.
1412 }
1413 template <class PARAM_1, class PARAM_2>
1414 pair(PARAM_1& a,
1415 PARAM_2& b,
1416 BloombergLP::bslma::Allocator *basicAllocator);
1417#endif
1418 // Construct a pair with the 'first' member initialized to the specified
1419 // 'a' value of (template parameter) type 'PARAM_1' and the 'second' member
1420 // initialized to the specified 'b' value of (template parameter) type
1421 // 'PARAM_2'. Optionally specify a 'basicAllocator', used to supply memory
1422 // for each of 'first' and 'second' when its type (template parameter 'T1'
1423 // or 'T2', respectively) uses 'bslma'-style allocators. This method
1424 // requires that 'T1' and 'T2' be convertible from 'PARAM_1' and 'PARAM_2',
1425 // respectively.
1426
1427#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY)
1428 template <class PARAM_1, class PARAM_2>
1431 typename bsl::enable_if<
1432 std::is_constructible<T1, const PARAM_1&>::value &&
1433 std::is_constructible<T2, const PARAM_2&>::value,
1434 SfinaeEnable>::type = SfinaeEnable());
1435 template <class PARAM_1, class PARAM_2>
1437 pair(const std::pair<PARAM_1, PARAM_2>& other,
1438 typename bsl::enable_if<
1439 std::is_constructible<T1, const PARAM_1&>::value &&
1440 std::is_constructible<T2, const PARAM_2&>::value,
1441 SfinaeEnable>::type = SfinaeEnable());
1442#else
1443 template <class PARAM_1, class PARAM_2>
1445 pair(const pair<PARAM_1, PARAM_2>& other);
1446 template <class PARAM_1, class PARAM_2>
1448 pair(const std::pair<PARAM_1, PARAM_2>& other);
1449#endif
1450 /// Construct a `pair` from the specified `other` pair, holding `first`
1451 /// and `second` values of (template parameter) type `PARAM_1` and
1452 /// `PARAM_2` respectively. Optionally specify a `basicAllocator`, used
1453 /// to supply memory for each of `first` and `second` when its type
1454 /// (template parameter `T1` or `T2`, respectively) uses `bslma`-style
1455 /// allocators. This method requires that `T1` and `T2` be convertible
1456 /// from `PARAM_1` and `PARAM_2`, respectively.
1457 template <class PARAM_1, class PARAM_2>
1459 BloombergLP::bslma::Allocator *basicAllocator);
1460 template <class PARAM_1, class PARAM_2>
1461 pair(const std::pair<PARAM_1, PARAM_2>& other,
1462 BloombergLP::bslma::Allocator *basicAllocator);
1463
1464#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
1465 /// Construct a `pair` from the specified `other` pair, holding `first`
1466 /// and `second` values of (template parameter) type `PARAM_1` and
1467 /// `PARAM_2` respectively. Optionally specify a `basicAllocator`, used
1468 /// to supply memory for each of `first` and `second` when its type
1469 /// (template parameter `T1` or `T2`, respectively) uses `bslma`-style
1470 /// allocators. This method requires that `T1` and `T2` be convertible
1471 /// from `PARAM_1` and `PARAM_2`, respectively.
1472 template <class PARAM_1, class PARAM_2>
1477 SfinaeEnable>::type = SfinaeEnable());
1478 template <class PARAM_1, class PARAM_2>
1480 pair(std::pair<PARAM_1, PARAM_2>&& other,
1483 SfinaeEnable>::type = SfinaeEnable());
1484 template <class PARAM_1, class PARAM_2>
1486 BloombergLP::bslma::Allocator *basicAllocator);
1487 template <class PARAM_1, class PARAM_2>
1488 pair(std::pair<PARAM_1, PARAM_2>&& other,
1489 BloombergLP::bslma::Allocator *basicAllocator);
1490#else
1491 template <class PARAM_1, class PARAM_2>
1493 pair(BloombergLP::bslmf::MovableRef<pair<PARAM_1, PARAM_2> > other,
1496 SfinaeEnable>::type = SfinaeEnable())
1497 : FirstBase(MovUtil::move(MovUtil::access(other).first))
1498 , SecondBase(MovUtil::move(MovUtil::access(other).second))
1499 {
1500 // The implementation is placed here in the class definition to work
1501 // around a Microsoft C++ compiler (version 16) bug where the
1502 // definition cannot be matched to the declaration when an 'enable_if'
1503 // is used.
1504 }
1505
1506 template <class PARAM_1, class PARAM_2>
1508 pair(BloombergLP::bslmf::MovableRef<std::pair<PARAM_1, PARAM_2> > other,
1511 SfinaeEnable>::type = SfinaeEnable())
1512 : FirstBase(MovUtil::move(MovUtil::access(other).first))
1513 , SecondBase(MovUtil::move(MovUtil::access(other).second))
1514 {
1515 // The implementation is placed here in the class definition to work
1516 // around a Microsoft C++ compiler (version 16) bug where the
1517 // definition cannot be matched to the declaration when an 'enable_if'
1518 // is used.
1519 }
1520
1521 /// Construct a `pair` from the specified `other` pair, holding `first`
1522 /// and `second` values of (template parameter) type `PARAM_1` and
1523 /// `PARAM_2` respectively. Optionally specify a `basicAllocator`, used
1524 /// to supply memory for each of `first` and `second` when its type
1525 /// (template parameter `T1` or `T2`, respectively) uses `bslma`-style
1526 /// allocators. This method requires that `T1` and `T2` be convertible
1527 /// from `PARAM_1` and `PARAM_2`, respectively.
1528 template <class PARAM_1, class PARAM_2>
1530 BloombergLP::bslmf::MovableRef<pair<PARAM_1, PARAM_2> > other,
1531 BloombergLP::bslma::Allocator *basicAllocator);
1532 template <class PARAM_1, class PARAM_2>
1533 pair(BloombergLP::bslmf::MovableRef<std::pair<PARAM_1, PARAM_2> > other,
1534 BloombergLP::bslma::Allocator *basicAllocator);
1535#endif
1536
1537#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR)
1538 /// Create a `pair` from piece-wise construction of `first` and `second`
1539 /// values by forwarding in order the elements in the specified
1540 /// @ref first_args and @ref second_args tuples to the corresponding
1541 /// constructor of (template parameter) types `T1` and `T2`,
1542 /// respectively. Optionally specify a `basicAllocator`, used to supply
1543 /// memory for each of `first` and `second` when its type (template
1544 /// parameter `T1` or `T2`, respectively) uses `bslma`-style allocators.
1545 /// Allocators can also be passed as tuple members straight to `T1` or
1546 /// `T2` (or both) constructors using the first version (but use of the
1547 /// second version for this approach will result in a compile-time
1548 /// error). This method requires that `T1` and `T2` be constructible
1549 /// from (the variable number of template parameters) `ARGS_1` and
1550 /// `ARGS_2` respectively.
1551 template<class ...ARGS_1, class ...ARGS_2>
1552 pair(std::piecewise_construct_t,
1553 std::tuple<ARGS_1...> first_args,
1554 std::tuple<ARGS_2...> second_args);
1555 template<class ...ARGS_1, class ...ARGS_2>
1556 pair(std::piecewise_construct_t,
1557 std::tuple<ARGS_1...> first_args,
1558 std::tuple<ARGS_2...> second_args,
1559 BloombergLP::bslma::Allocator *basicAllocator);
1560#endif
1561
1562#ifndef BDE_OMIT_INTERNAL_DEPRECATED
1563 /// Create a `pair` that has the same value as the specified `rhs` pair
1564 /// proxy. The behavior is undefined unless `T1` is constructible from
1565 /// `PARAM_1` and `T2` is constructible from from `PARAM_2`.
1566 template <class PARAM_1, class PARAM_2>
1568 pair(const BloombergLP::bslma::ManagedPtr_PairProxy<PARAM_1, PARAM_2>&
1569 rhs); // IMPLICIT
1570#endif // BDE_OMIT_INTERNAL_DEPRECATED
1571
1572 ~pair() = default;
1573 // Destroy this object. Call destructors on 'first' and 'second'.
1574
1575 // MANIPULATORS
1576
1577 /// Assign to this `pair` from the specified `rhs` pair, holding the
1578 /// parameterized types `PARAM_1` and `PARAM_2`, and return a reference
1579 /// offering modifiable access to this object. Assign `first` the value
1580 /// in `rhs.first` and `second` the value in `rhs.second`. Attempted
1581 /// use of this assignment operator will not compile unless both `T1`
1582 /// and `T2` supply assignment operators, and `T1` is assignable from
1583 /// `PARAM_1` and `T2` is assignable from `PARAM_2`.
1584 template <class PARAM_1, class PARAM_2>
1586
1587#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
1588 /// Assign to this `pair` the value of the specified `rhs` pair, holding
1589 /// `first` and `second` values of (template parameter) type `PARAM_1`
1590 /// and `PARAM_2` respectively, and return a reference providing
1591 /// modifiable access to this object. This method requires that `T1` be
1592 /// assignable from `PARAM_1` and `T2` be assignable from `PARAM_2`.
1593 template <class PARAM_1, class PARAM_2>
1595#else
1596 pair& operator=(BloombergLP::bslmf::MovableRef<pair> rhs)
1598 // Assign to this 'pair' the value of the specified 'rhs' pair (before
1599 // the call to the assignment), and return a reference providing
1600 // modifiable access to this object. Note that 'rhs' is left in a
1601 // valid but unspecified state. This method requires that (template
1602 // parameter) types 'T1' and 'T2' be move-assignable.
1603
1604 /// Assign to this `pair` the value of the specified `rhs` pair, holding
1605 /// `first` and `second` values of (template parameter) types `PARAM_1`
1606 /// and `PARAM_2` respectively, and return a reference providing
1607 /// modifiable access to this object. This method requires that `T1` be
1608 /// assignable from `PARAM_1` and `T2` be assignable from `PARAM_2`.
1609 template <class PARAM_1, class PARAM_2>
1611 BloombergLP::bslmf::MovableRef<pair<PARAM_1, PARAM_2> > rhs);
1612#endif
1613
1614 /// Assign to this `pair` from the specified `rhs` pair, where the type
1615 /// `rhs` is the pair type native to the compiler's library, holding the
1616 /// parameterized types `PARAM_1` and `PARAM_2`, and return a reference
1617 /// offering modifiable access to this object. Assign `first` the value
1618 /// in `rhs.first` and `second` the value in `rhs.second`. Attempted
1619 /// use of this assignment operator will not compile unless both `T1`
1620 /// and `T2` supply assignment operators, and `T1` is assignable from
1621 /// `PARAM_1` and `T2` is assignable from `PARAM_2`.
1622 template <class PARAM_1, class PARAM_2>
1623 pair& operator=(const std::pair<PARAM_1, PARAM_2>& rhs);
1624
1625#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE)
1626 /// Return an `std::tuple` object, holding references that provide
1627 /// modifiable access to the members of this object.
1628 template <class PARAM_1, class PARAM_2,
1631 bool>::type = 0>
1632 operator std::tuple<PARAM_1&, PARAM_2&>() BSLS_KEYWORD_NOEXCEPT;
1633
1634 template <class PARAM_1,
1635 typename bsl::enable_if<bsl::is_convertible<T1, PARAM_1>::value,
1636 bool>::type = 0>
1637 operator std::tuple<PARAM_1&, decltype(std::ignore)&>()
1639 // This partial specialization of 'template <class PARAM_1, class PARAM_2>
1640 // operator std::tuple<PARAM_1&, PARAM_2&>()', for when the (template
1641 // parameter) 'PARAM_2' (second element's type) is the type of
1642 // 'std::ignore'.
1643
1644 template <class PARAM_2,
1645 typename bsl::enable_if<bsl::is_convertible<T2, PARAM_2>::value,
1646 bool>::type = 0>
1647 operator std::tuple<decltype(std::ignore)&, PARAM_2&>()
1649 // This partial specialization of 'template <class PARAM_1, class PARAM_2>
1650 // operator std::tuple<PARAM_1&, PARAM_2&>()', for when the (template
1651 // parameter) 'PARAM_1' (first element's type) is the type of
1652 // 'std::ignore'.
1653
1654 operator std::tuple<decltype(std::ignore)&,
1655 decltype(std::ignore)&>() BSLS_KEYWORD_NOEXCEPT
1656 // This partial specialization of 'template <class PARAM_1, class PARAM_2>
1657 // operator std::tuple<PARAM_1&, PARAM_2&>()', for when the (template
1658 // parameters) 'PARAM_1' (first element's type) and 'PARAM_2' (second
1659 // element's type) are the type of 'std::ignore'. Note that this method is
1660 // defined within the class body intentionally to avoid build failure on
1661 // MSVC 2015.
1662 {
1663 return std::tuple<decltype(std::ignore)&,
1664 decltype(std::ignore)&>(std::ignore,
1665 std::ignore);
1666 }
1667#endif
1668
1669#if defined(BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE)
1670 void swap(pair& other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(
1671 Pair_ImpUtil::hasNothrowSwap<T1, T2>());
1672#else
1673 void swap(pair& other)
1674 BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(bsl::is_nothrow_swappable<T1>::value
1675 && bsl::is_nothrow_swappable<T2>::value);
1676#endif
1677 // Swap the value of this pair with the value of the specified 'other'
1678 // pair by applying 'swap' to each of the 'first' and 'second' pair
1679 // fields. Note that this method is no-throw only if 'swap' on each
1680 // field is no-throw.
1681};
1682
1683#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
1684// CLASS TEMPLATE DEDUCTION GUIDES
1685
1686// When we are deducing from a 'pair<T1, T2>' (std or bsl) and an
1687// 'Allocator *', we want to deduce a 'bsl::pair<T1, T2>', not a
1688// bsl::pair<pair<T1, T2>, Allocator *>.
1689//
1690// Note that order is important; if given an 'Allocator *' and a
1691// 'pair<T1, T2>' we deduce 'bsl::pair<Allocator *, pair<T1, T2>>'.
1692
1693/// Deduce the specified types `T1` and `T2` from the corresponding types
1694/// supplied to the constructor of `pair`.
1695template <class T1, class T2>
1696pair(T1, T2) -> pair<T1, T2>;
1697
1698/// Deduce the specified types `T1` and `T2` from the corresponding types
1699/// supplied to the constructor of `pair`. This guide does not participate
1700/// in deduction unless the specified `ALLOC` inherits from
1701/// `bslma::Allocator`.
1702template <
1703 class T1,
1704 class T2,
1705 class ALLOC,
1706 class = typename bsl::enable_if_t<
1707 bsl::is_convertible_v<ALLOC *, BloombergLP::bslma::Allocator *>>
1708 >
1709pair(T1, T2, ALLOC *) -> pair<T1, T2>;
1710
1711/// Deduce the specified types `T1` and `T2` from the corresponding template
1712/// parameters of the `bsl::pair` supplied to the constructor of `pair`.
1713/// This guide does not participate in deduction unless the specified
1714/// `ALLOC` inherits from `bslma::Allocator`.
1715template <
1716 class T1,
1717 class T2,
1718 class ALLOC,
1719 class = typename bsl::enable_if_t<
1720 bsl::is_convertible_v<ALLOC *, BloombergLP::bslma::Allocator *>>
1721 >
1722pair(pair<T1, T2>, ALLOC *) -> pair<T1, T2>;
1723
1724/// Deduce the specified types `T1` and `T2` from the corresponding template
1725/// parameters of the `std::pair` supplied to the constructor of `pair`.
1726template <class T1, class T2>
1727pair(std::pair<T1, T2>) -> pair<T1, T2>;
1728
1729/// Deduce the specified types `T1` and `T2` from the corresponding template
1730/// parameters of the `std::pair` supplied to the constructor of `pair`.
1731/// This guide does not participate in deduction unless the specified
1732/// `ALLOC` inherits from `bslma::Allocator`.
1733template <
1734 class T1,
1735 class T2,
1736 class ALLOC,
1737 class = typename bsl::enable_if_t<
1738 bsl::is_convertible_v<ALLOC *, BloombergLP::bslma::Allocator *>>
1739 >
1740pair(std::pair<T1, T2>, ALLOC *) -> pair<T1, T2>;
1741#endif
1742
1743// FREE OPERATORS
1744
1745/// Return true if the specified `lhs` and `rhs` pair objects have the same
1746/// value and false otherwise. `lhs` has the same value as `rhs` if
1747/// `lhs.first == rhs.first` and `lhs.second == rhs.second`. A call to this
1748/// operator will not compile unless both `T1` and `T2` supply `operator==`.
1749template <class T1, class T2>
1750inline
1752bool operator==(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs);
1753
1754#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1755/// Return true if the specified `lhs` and `rhs` pair objects do not have
1756/// the same value and false otherwise. `lhs` does not have the same value
1757/// as `rhs` if `lhs == rhs` would return false. A call to this operator
1758/// will not compile unless a call to `lhs == rhs` would compile.
1759template <class T1, class T2>
1760inline
1762bool operator!=(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs);
1763#endif
1764
1765#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1766
1767/// Perform a lexicographic three-way comparison of the specified `lhs` and
1768/// the specified `rhs` pairs by using the comparison operators of `T1` and
1769/// `T2`; return the result of that comparison.
1770template <class T1, class T2>
1772std::common_comparison_category_t<
1773 BloombergLP::bslalg::SynthThreeWayUtil::Result<T1>,
1774 BloombergLP::bslalg::SynthThreeWayUtil::Result<T2>
1775> operator<=>(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs);
1776
1777#else
1778
1779/// Return true if the specified `lhs` has a value less than the specified
1780/// `rhs` and false otherwise. Whether or not `lhs` is less than `rhs` is
1781/// determined by a lexicographical comparison of the `first` and `second`
1782/// data members of `lhs` and `rhs`. In other words: return true if
1783/// `lhs.first < rhs.first` and false if `rhs.first < lhs.first`, otherwise
1784/// return `lhs.second < rhs.second`. A call to this operator will not
1785/// compile unless both `T1` and `T2` supply `operator<`.
1786template <class T1, class T2>
1787inline
1789bool operator<(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs);
1790
1791/// Return true if the specified `lhs` has a value greater than the
1792/// specified `rhs` and false otherwise. `lhs` has a value greater than
1793/// `rhs` if `rhs` < `lhs` would return true. A call to this operator will
1794/// not compile unless a call to `lhs < rhs` would compile.
1795template <class T1, class T2>
1796inline
1798bool operator>(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs);
1799
1800/// Return true if the specified `lhs` has a value less than or equal to the
1801/// specified `rhs` and false otherwise. `lhs` has a value less than or
1802/// equal to `rhs` if `rhs` < `lhs` would return false. A call to this
1803/// operator will not compile unless a call to `lhs < rhs` would compile.
1804template <class T1, class T2>
1805inline
1807bool operator<=(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs);
1808
1809/// Return true if the specified `lhs` has a value greater than or equal to
1810/// the specified `rhs` and false otherwise. `lhs` has a value greater than
1811/// or equal to `rhs` if `lhs` < `rhs` would return false. A call to this
1812/// operator will not compile unless a call to `lhs < rhs` would compile.
1813template <class T1, class T2>
1814inline
1816bool operator>=(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs);
1817
1818#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1819
1820// FREE FUNCTIONS
1821
1822/// Swap the values of the specified `a` and `b` pairs by applying `swap` to
1823/// each of the `first` and `second` pair fields. Note that this method is
1824/// no-throw only if `swap` on each field is no-throw.
1825template <class T1, class T2>
1826#if defined(BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE)
1827void
1828#else
1830 && bsl::is_swappable<T2>::value>::type
1831#endif
1832swap(pair<T1, T2>& a, pair<T1, T2>& b)
1834
1835// HASH SPECIALIZATIONS
1836
1837/// Pass the specified `input` to the specified `hashAlg`
1838template <class HASHALG, class T1, class T2>
1839void hashAppend(HASHALG& hashAlg, const pair<T1, T2>& input);
1840
1841} // close namespace bsl
1842
1843#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE)
1844
1845namespace std {
1846
1847#if defined(BSLS_PLATFORM_CMP_CLANG)
1848#pragma clang diagnostic push
1849#pragma clang diagnostic ignored "-Wmismatched-tags"
1850#endif
1851
1852 // ====================
1853 // struct tuple_element
1854 // ====================
1855
1856/// This partial specialization of @ref tuple_element provides compile-time
1857/// access to the type of the pair's first element.
1858template<class T1, class T2>
1859struct tuple_element<0, bsl::pair<T1, T2> >
1860{
1861 // TYPES
1862 typedef T1 type;
1863};
1864
1865/// This partial specialization of @ref tuple_element provides compile-time
1866/// access to the type of the pair's second element.
1867template<class T1, class T2>
1868struct tuple_element<1, bsl::pair<T1, T2> >
1869{
1870 // TYPES
1871 typedef T2 type;
1872};
1873
1874 // =================
1875 // struct tuple_size
1876 // =================
1877
1878/// This meta-function provides a compile-time way to obtain the number of
1879/// elements in a pair, which is always 2.
1880template<class T1, class T2>
1881struct tuple_size<bsl::pair<T1, T2> > : integral_constant<size_t, 2>
1882{};
1883
1884#if defined(BSLS_PLATFORM_CMP_CLANG)
1885#pragma clang diagnostic pop
1886#endif
1887
1888} // close namespace std
1889
1890
1891namespace bslstl {
1892
1893 // =====================
1894 // class Pair_GetImpUtil
1895 // =====================
1896
1897/// This utility class template provides functions for selecting the element
1898/// of pair, returned from `bsl::get(bsl::pair<T1, T2>)`, by its index.
1899template <std::size_t INDEX, class T1, class T2>
1900struct Pair_GetImpUtil
1901{
1902 BSLMF_ASSERT(INDEX < 2);
1903};
1904
1905/// This partial specialization of `Pair_GetImpUtil`, for when the
1906/// (template parameter) `INDEX`(element's index) is equal to 0.
1907template <class T1, class T2>
1908struct Pair_GetImpUtil<0, T1, T2>
1909{
1910 private:
1911 // PRIVATE TYPES
1912
1913 /// This typedef is a convenient alias for the utility associated with
1914 /// implementing movable references in C++03 and C++11 environments.
1915 typedef bslmf::MovableRefUtil MovUtil;
1916
1917 public:
1918 // CLASS METHODS
1919
1920 /// Return a reference providing modifiable access to the first element
1921 /// of the specified `p`.
1922 static T1& getPairElement(bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT;
1923
1924 /// Return a reference providing non-modifiable access to the first
1925 /// element of the specified `p`.
1926 static
1927 const T1& getPairElement(const bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT;
1928
1929#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
1930 /// Return a rvalue reference providing modifiable access to the first
1931 /// element of the specified `p`
1932 static T1&&
1933 getPairElement(bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT;
1934
1935 /// Return a rvalue reference providing non-modifiable access to the
1936 /// first element of the specified `p`
1937 static const T1&&
1938 getPairElement(const bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT;
1939
1940#endif
1941};
1942
1943/// This partial specialization of `Pair_GetImpUtil`, for when the
1944/// (template parameter) `INDEX`(element's index) is equal to 1.
1945template <class T1, class T2>
1946struct Pair_GetImpUtil<1u, T1, T2>
1947{
1948 private:
1949 // PRIVATE TYPES
1950
1951 /// This typedef is a convenient alias for the utility associated with
1952 /// implementing movable references in C++03 and C++11 environments.
1953 typedef bslmf::MovableRefUtil MovUtil;
1954
1955 public:
1956 // CLASS METHODS
1957
1958 /// Return a reference providing modifiable access to the second element
1959 /// of the specified `p`.
1960 static T2& getPairElement(bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT;
1961
1962 /// Return a reference providing non-modifiable access to the second
1963 /// element of the specified `p`.
1964 static
1965 const T2& getPairElement(const bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT;
1966
1967#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
1968 /// Return a rvalue reference providing modifiable access to the second
1969 /// element of the specified `p`
1970 static T2&&
1971 getPairElement(bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT;
1972
1973 /// Return a rvalue reference providing non-modifiable access to the
1974 /// second element of the specified `p`
1975 static const T2&&
1976 getPairElement(const bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT;
1977#endif
1978};
1979
1980/// This meta-function provides a compile-time way to obtain the index of
1981/// `bsl::pair` element, having the (template parameter) type `T`. If
1982/// neither type of pair's element is equal to `T` or both pair's elements
1983/// have the same type, code is not compiled.
1984template <class T, class T1, class T2>
1985struct Pair_IndexOfType
1986{};
1987
1988/// This partial specialization of `Pair_IndexOfType` returns the index of
1989/// first element of pair.
1990template <class T1, class T2>
1991struct Pair_IndexOfType<T1, T1, T2> : bsl::integral_constant<size_t, 0>
1992{};
1993
1994/// This partial specialization of `Pair_IndexOfType` returns the index of
1995/// second element of pair.
1996template <class T1, class T2>
1997struct Pair_IndexOfType<T2, T1, T2> : bsl::integral_constant<size_t, 1u>
1998{};
1999
2000} // close package namespace
2001
2002
2003namespace bsl {
2004
2005// FREE FUNCTIONS
2006
2007/// Return a reference providing modifiable access to the element of the
2008/// specified `p`, having the ordinal number specified by the (template
2009/// parameter) `INDEX`. This function will not compile unless the `INDEX`
2010/// is either 0 or 1.
2011template<std::size_t INDEX, class T1, class T2>
2012typename std::tuple_element<INDEX, bsl::pair<T1, T2> >::type&
2014
2015/// Return a reference providing non-modifiable access to the element of the
2016/// specified `p`, having the ordinal number specified by the (template
2017/// parameter) `INDEX`. This function will not compile unless the `INDEX`
2018/// is either 0 or 1.
2019template<std::size_t INDEX, class T1, class T2>
2020const typename std::tuple_element<INDEX, bsl::pair<T1, T2> >::type&
2022
2023#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2024/// Return a rvalue reference providing modifiable access to the element of
2025/// the specified `p`, having the ordinal number specified by the (template
2026/// parameter) `INDEX`. This function will not compile unless the `INDEX`
2027/// is either 0 or 1.
2028template<std::size_t INDEX, class T1, class T2>
2029typename std::tuple_element<INDEX, bsl::pair<T1, T2> >::type&&
2031#endif
2032
2033/// Return a reference providing modifiable access to the element of the
2034/// specified `p`, having the (template parameter) `TYPE`. This function
2035/// will not compile unless the types `T1` and `T2` are different and the
2036/// `TYPE` is the same as either `T1` or `T2`.
2037template<class TYPE, class T1, class T2>
2039
2040/// Return a reference providing non-modifiable access to the element of the
2041/// specified `p`, having the (template parameter) `TYPE`. This function
2042/// will not compile unless the types `T1` and `T2` are different and the
2043/// `TYPE` is the same as either `T1` or `T2`.
2044template<class TYPE, class T1, class T2>
2045const TYPE& get(const bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT;
2046
2047#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2048/// Return a rvalue reference providing modifiable access to the element of
2049/// the specified `p`, having the (template parameter) `TYPE`. This
2050/// function will not compile unless the types `T1` and `T2` are different
2051/// and the `TYPE` is the same as either `T1` or `T2`.
2052template<class TYPE, class T1, class T2>
2054
2055/// Return a rvalue reference providing non-modifiable access to the element
2056/// of the specified `p`, having the (template parameter) `TYPE`. This
2057/// function will not compile unless the types `T1` and `T2` are different
2058/// and the `TYPE` is the same as either `T1` or `T2`.
2059template<class TYPE, class T1, class T2>
2060const TYPE&& get(const bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT;
2061#endif
2062
2063} // close bsl namespace
2064
2065#endif
2066
2067
2068// ============================================================================
2069// INLINE FUNCTION DEFINITIONS
2070// ============================================================================
2071// See IMPLEMENTATION NOTES in the .cpp before modifying anything below.
2072
2073namespace bsl {
2074 // -------------------
2075 // struct Pair_ImpUtil
2076 // -------------------
2077#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE)
2078template <class ... ARGS>
2079inline
2080std::tuple<ARGS...>
2081Pair_ImpUtil::concatAllocator(
2082 BSLS_COMPILERFEATURES_FORWARD_REF(std::tuple<ARGS...>) tpl,
2083 BloombergLP::bslma::Allocator *,
2085{
2086 return BloombergLP::bslmf::MovableRefUtil::move(tpl);
2087}
2088
2089template <class ... ARGS>
2090inline
2091std::tuple<ARGS..., BloombergLP::bslma::Allocator *>
2092Pair_ImpUtil::concatAllocator(
2093 BSLS_COMPILERFEATURES_FORWARD_REF(std::tuple<ARGS...>) tpl,
2094 BloombergLP::bslma::Allocator *alloc,
2096{
2097 return std::tuple_cat(BloombergLP::bslmf::MovableRefUtil::move(tpl),
2098 std::tie(alloc));
2099}
2100
2101template <class ... ARGS>
2102inline
2103std::tuple<bsl::allocator_arg_t,
2104 BloombergLP::bslma::Allocator *,
2105 ARGS...>
2106Pair_ImpUtil::concatAllocator(
2107 BSLS_COMPILERFEATURES_FORWARD_REF(std::tuple<ARGS...>) tpl,
2108 BloombergLP::bslma::Allocator *alloc,
2110{
2111 return std::tuple_cat(std::tie(bsl::allocator_arg, alloc),
2112 BloombergLP::bslmf::MovableRefUtil::move(tpl));
2113}
2114#endif
2115
2116 // -----------------
2117 // struct Pair_First
2118 // -----------------
2119
2120// CREATORS
2121#if defined(BSLSTL_PAIR_DO_NOT_DEFAULT_THE_DEFAULT_CONSTRUCTOR)
2122template <class TYPE>
2123inline
2126: first()
2127{
2128}
2129#endif
2130
2131template <class TYPE>
2132inline
2133Pair_First<TYPE>::Pair_First(BloombergLP::bslma::Allocator *,
2135: first()
2136{
2137}
2138
2139template <class TYPE>
2140inline
2141Pair_First<TYPE>::Pair_First(BloombergLP::bslma::Allocator *basicAllocator,
2143: first(basicAllocator)
2144{
2145}
2146
2147template <class TYPE>
2148inline
2149Pair_First<TYPE>::Pair_First(BloombergLP::bslma::Allocator *basicAllocator,
2151: first(bsl::allocator_arg, basicAllocator)
2152{
2153}
2154
2155template <class TYPE>
2156inline
2160: first(value)
2161{
2162}
2163
2164#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2165template <class TYPE>
2166template <class PARAM>
2167inline
2170 PARAM&& value,
2171 typename std::enable_if<
2172 !std::is_same<Pair_First,
2173 typename std::remove_cv<typename std::remove_reference<
2174 PARAM>::type>::type>::value,
2175 SfinaeEnable>::type)
2176: first(BSLS_COMPILERFEATURES_FORWARD(PARAM, value))
2177{
2178}
2179#else
2180template <class TYPE>
2181template <class PARAM>
2182inline
2185: first(value)
2186{
2187}
2188
2189template <class TYPE>
2190template <class PARAM>
2191inline
2194: first(value)
2195{
2196}
2197#endif
2198
2199#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2200template <class TYPE>
2201template <class PARAM>
2202inline
2203Pair_First<TYPE>::Pair_First(PARAM&& value,
2204 BloombergLP::bslma::Allocator *,
2206: first(BSLS_COMPILERFEATURES_FORWARD(PARAM,value))
2207{
2208}
2209
2210template <class TYPE>
2211template <class PARAM>
2212inline
2213Pair_First<TYPE>::Pair_First(PARAM&& value,
2214 BloombergLP::bslma::Allocator *basicAllocator,
2216: first(BSLS_COMPILERFEATURES_FORWARD(PARAM, value), basicAllocator)
2217{
2218}
2219
2220template <class TYPE>
2221template <class PARAM>
2222inline
2223Pair_First<TYPE>::Pair_First(PARAM&& value,
2224 BloombergLP::bslma::Allocator *basicAllocator,
2226: first(bsl::allocator_arg,
2227 basicAllocator,
2228 BSLS_COMPILERFEATURES_FORWARD(PARAM, value))
2229{
2230}
2231#else
2232template <class TYPE>
2233template <class PARAM>
2234inline
2236 BloombergLP::bslma::Allocator *,
2238: first(value)
2239{
2240}
2241
2242template <class TYPE>
2243template <class PARAM>
2244inline
2246 BloombergLP::bslma::Allocator *,
2248: first(value)
2249{
2250}
2251
2252template <class TYPE>
2253template <class PARAM>
2254inline
2256 BloombergLP::bslma::Allocator *basicAllocator,
2258: first(value, basicAllocator)
2259{
2260}
2261
2262template <class TYPE>
2263template <class PARAM>
2264inline
2266 BloombergLP::bslma::Allocator *basicAllocator,
2268: first(value, basicAllocator)
2269{
2270}
2271
2272template <class TYPE>
2273template <class PARAM>
2274inline
2276 BloombergLP::bslma::Allocator *basicAllocator,
2278: first(bsl::allocator_arg, basicAllocator, value)
2279{
2280}
2281
2282template <class TYPE>
2283template <class PARAM>
2284inline
2286 BloombergLP::bslma::Allocator *basicAllocator,
2288: first(bsl::allocator_arg, basicAllocator, value)
2289{
2290}
2291#endif
2292
2293#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \
2294 && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE)
2295template <class TYPE>
2296template <class ...ARGS, size_t ...I>
2297inline
2298
2299Pair_First<TYPE>::Pair_First(std::tuple<ARGS...>&& argsPack,
2300 BloombergLP::bslstl::Pair_IndexSequence<I...>)
2301: first(std::get<I>(std::move(argsPack))...)
2302{
2303}
2304#endif
2305
2306 // ------------------------
2307 // struct Pair_First<TYPE&>
2308 // ------------------------
2309
2310// CREATORS
2311
2312template <class TYPE>
2314inline
2316: first(value)
2317{
2318}
2319
2320#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2321template <class TYPE>
2322template <class PARAM>
2324inline
2325Pair_First<TYPE&>::Pair_First(PARAM&& value)
2326: first(std::forward<PARAM>(value))
2327{
2328}
2329#else
2330template <class TYPE>
2331template <class PARAM>
2333inline
2335: first(value)
2336{
2337}
2338
2339template <class TYPE>
2340template <class PARAM>
2342inline
2344: first(value)
2345{
2346}
2347#endif
2348
2349#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2350template <class TYPE>
2351template <class PARAM>
2353inline
2354Pair_First<TYPE&>::Pair_First(PARAM&& value,
2355 BloombergLP::bslma::Allocator *,
2357: first(std::forward<PARAM>(value))
2358{
2359}
2360#else
2361template <class TYPE>
2362template <class PARAM>
2364inline
2366 BloombergLP::bslma::Allocator *,
2368: first(value)
2369{
2370}
2371
2372template <class TYPE>
2373template <class PARAM>
2375inline
2377 BloombergLP::bslma::Allocator *,
2379: first(value)
2380{
2381}
2382#endif
2383
2384#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \
2385 && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE)
2386template <class TYPE>
2387template <class ARG>
2389inline
2390Pair_First<TYPE&>::Pair_First(std::tuple<ARG>&& arg,
2391 BloombergLP::bslstl::Pair_IndexSequence<0u>)
2392: first(std::get<0u>(arg))
2393{
2394}
2395#endif
2396
2397// MANIPULATORS
2398
2399template <class TYPE>
2400inline
2403{
2404 first = rhs.first;
2405 return *this;
2406}
2407
2408#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2409 // -------------------------
2410 // struct Pair_First<TYPE&&>
2411 // -------------------------
2412
2413// CREATORS
2414
2415template <class TYPE>
2417inline
2419: first(std::move(value))
2420{
2421}
2422
2423template <class TYPE>
2424template <class PARAM>
2426inline
2427Pair_First<TYPE&&>::Pair_First(PARAM&& value)
2428: first(std::forward<PARAM>(value))
2429{
2430}
2431
2432template <class TYPE>
2433template <class PARAM>
2435inline
2436Pair_First<TYPE&&>::Pair_First(PARAM&& value,
2437 BloombergLP::bslma::Allocator *,
2439: first(std::forward<PARAM>(value))
2440{
2441}
2442
2443#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \
2444 && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE)
2445template <class TYPE>
2446template <class ARG>
2448inline
2449Pair_First<TYPE&&>::Pair_First(std::tuple<ARG>&& arg,
2450 BloombergLP::bslstl::Pair_IndexSequence<0u>)
2451: first(std::get<0u>(arg))
2452{
2453}
2454#endif
2455
2456// MANIPULATORS
2457template <class TYPE>
2458inline
2459Pair_First<TYPE&&>& Pair_First<TYPE&&>::operator=(const Pair_First& rhs)
2461{
2462 first = rhs.first;
2463 return *this;
2464}
2465#endif
2466
2467 // ------------------
2468 // struct Pair_Second
2469 // ------------------
2470
2471// CREATORS
2472#if defined(BSLSTL_PAIR_DO_NOT_DEFAULT_THE_DEFAULT_CONSTRUCTOR)
2473template <class TYPE>
2474inline
2477: second()
2478{
2479}
2480#endif
2481
2482template <class TYPE>
2483inline
2484Pair_Second<TYPE>::Pair_Second(BloombergLP::bslma::Allocator *,
2486: second()
2487{
2488}
2489
2490template <class TYPE>
2491inline
2492Pair_Second<TYPE>::Pair_Second(BloombergLP::bslma::Allocator *basicAllocator,
2494: second(basicAllocator)
2495{
2496}
2497
2498template <class TYPE>
2499inline
2500Pair_Second<TYPE>::Pair_Second(BloombergLP::bslma::Allocator *basicAllocator,
2502: second(bsl::allocator_arg, basicAllocator)
2503{
2504}
2505
2506template <class TYPE>
2507inline
2511: second(value)
2512{
2513}
2514
2515#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2516template <class TYPE>
2517template <class PARAM>
2518inline
2521 PARAM&& value,
2522 typename std::enable_if<
2523 !std::is_same<Pair_Second,
2524 typename std::remove_cv<typename std::remove_reference<
2525 PARAM>::type>::type>::value,
2526 SfinaeEnable>::type)
2527: second(BSLS_COMPILERFEATURES_FORWARD(PARAM, value))
2528{
2529}
2530#else
2531template <class TYPE>
2532template <class PARAM>
2533inline
2536: second(value)
2537{
2538}
2539template <class TYPE>
2540template <class PARAM>
2541inline
2544: second(value)
2545{
2546}
2547#endif
2548
2549#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2550template <class TYPE>
2551template <class PARAM>
2552inline
2553Pair_Second<TYPE>::Pair_Second(PARAM&& value,
2554 BloombergLP::bslma::Allocator *,
2556: second(BSLS_COMPILERFEATURES_FORWARD(PARAM, value))
2557{
2558}
2559
2560template <class TYPE>
2561template <class PARAM>
2562inline
2563Pair_Second<TYPE>::Pair_Second(PARAM&& value,
2564 BloombergLP::bslma::Allocator *basicAllocator,
2566: second(BSLS_COMPILERFEATURES_FORWARD(PARAM, value), basicAllocator)
2567{
2568}
2569
2570template <class TYPE>
2571template <class PARAM>
2572inline
2573Pair_Second<TYPE>::Pair_Second(PARAM&& value,
2574 BloombergLP::bslma::Allocator *basicAllocator,
2576: second(bsl::allocator_arg,
2577 basicAllocator,
2578 BSLS_COMPILERFEATURES_FORWARD(PARAM, value))
2579{
2580}
2581#else
2582template <class TYPE>
2583template <class PARAM>
2584inline
2586 BloombergLP::bslma::Allocator *,
2588: second(value)
2589{
2590}
2591
2592template <class TYPE>
2593template <class PARAM>
2594inline
2596 BloombergLP::bslma::Allocator *,
2598: second(value)
2599{
2600}
2601
2602template <class TYPE>
2603template <class PARAM>
2604inline
2606 BloombergLP::bslma::Allocator *basicAllocator,
2608: second(value, basicAllocator)
2609{
2610}
2611
2612template <class TYPE>
2613template <class PARAM>
2614inline
2616 BloombergLP::bslma::Allocator *basicAllocator,
2618: second(value, basicAllocator)
2619{
2620}
2621
2622template <class TYPE>
2623template <class PARAM>
2624inline
2626 BloombergLP::bslma::Allocator *basicAllocator,
2628: second(bsl::allocator_arg, basicAllocator, value)
2629{
2630}
2631
2632template <class TYPE>
2633template <class PARAM>
2634inline
2636 BloombergLP::bslma::Allocator *basicAllocator,
2638: second(bsl::allocator_arg, basicAllocator, value)
2639{
2640}
2641#endif
2642
2643#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \
2644 && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE)
2645template <class TYPE>
2646template <class ...ARGS, size_t ...I>
2647inline
2648Pair_Second<TYPE>::Pair_Second(std::tuple<ARGS...>&& argsPack,
2649 BloombergLP::bslstl::Pair_IndexSequence<I...>)
2650: second(std::get<I>(std::move(argsPack))...)
2651{
2652}
2653#endif
2654
2655 // -------------------------
2656 // struct Pair_Second<TYPE&>
2657 // -------------------------
2658
2659 // CREATORS
2660template <class TYPE>
2662inline
2664: second(value)
2665{
2666}
2667
2668#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2669template <class TYPE>
2670template <class PARAM>
2672inline
2674: second(std::forward<PARAM>(value))
2675{
2676}
2677#else
2678template <class TYPE>
2679template <class PARAM>
2681inline
2683: second(value)
2684{
2685}
2686
2687template <class TYPE>
2688template <class PARAM>
2690inline
2692: second(value)
2693{
2694}
2695#endif
2696
2697#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2698template <class TYPE>
2699template <class PARAM>
2701inline
2703 BloombergLP::bslma::Allocator *,
2705: second(std::forward<PARAM>(value))
2706{
2707}
2708#else
2709template <class TYPE>
2710template <class PARAM>
2712inline
2714 BloombergLP::bslma::Allocator *,
2716: second(value)
2717{
2718}
2719
2720template <class TYPE>
2721template <class PARAM>
2723inline
2725 BloombergLP::bslma::Allocator *,
2727: second(value)
2728{
2729}
2730#endif
2731
2732#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \
2733 && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE)
2734template <class TYPE>
2735template <class ARG>
2737inline
2738Pair_Second<TYPE&>::Pair_Second(std::tuple<ARG>&& arg,
2739 BloombergLP::bslstl::Pair_IndexSequence<0u>)
2740: second(std::get<0u>(arg))
2741{
2742}
2743#endif
2744
2745// MANIPULATORS
2746template <class TYPE>
2747inline
2750{
2751 second = rhs.second;
2752 return *this;
2753}
2754
2755
2756#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2757 // --------------------------
2758 // struct Pair_Second<TYPE&&>
2759 // --------------------------
2760
2761// CREATORS
2762template <class TYPE>
2765: second(std::move(value))
2766{
2767}
2768
2769template <class TYPE>
2770template <class PARAM>
2772inline
2774: second(std::forward<PARAM>(value))
2775{
2776}
2777
2778template <class TYPE>
2779template <class PARAM>
2781inline
2783 BloombergLP::bslma::Allocator *,
2785: second(std::forward<PARAM>(value))
2786{
2787}
2788
2789#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \
2790 && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE)
2791template <class TYPE>
2792template <class ARG>
2794inline
2795Pair_Second<TYPE&&>::Pair_Second(std::tuple<ARG>&& arg,
2796 BloombergLP::bslstl::Pair_IndexSequence<0u>)
2797: second(std::get<0u>(arg))
2798{
2799}
2800#endif
2801
2802// MANIPULATORS
2803template <class TYPE>
2804inline
2805Pair_Second<TYPE&&>& Pair_Second<TYPE&&>::operator=(const Pair_Second& rhs)
2807{
2808 second = rhs.second;
2809 return *this;
2810}
2811#endif
2812 // ----------
2813 // class pair
2814 // ----------
2815
2816// CREATORS
2817#if defined(BSLSTL_PAIR_DO_NOT_DEFAULT_THE_DEFAULT_CONSTRUCTOR)
2818template <class T1, class T2>
2819inline
2822: FirstBase()
2823, SecondBase()
2824{
2825}
2826#endif
2827
2828template <class T1, class T2>
2829inline
2830pair<T1, T2>::pair(BloombergLP::bslma::Allocator *basicAllocator)
2831: FirstBase(basicAllocator, FirstBslmaIdiom())
2832, SecondBase(basicAllocator, SecondBslmaIdiom())
2833{
2834}
2835
2836template <class T1, class T2>
2838inline
2845
2846template <class T1, class T2>
2847inline
2851 BloombergLP::bslma::Allocator *basicAllocator)
2852: FirstBase(a, basicAllocator, FirstBslmaIdiom())
2853, SecondBase(b, basicAllocator, SecondBslmaIdiom())
2854{
2855}
2856
2857#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2858template <class T1, class T2>
2859template <class PARAM_1, class PARAM_2>
2860inline
2861pair<T1, T2>::pair(PARAM_1&& a,
2862 PARAM_2&& b,
2863 BloombergLP::bslma::Allocator *basicAllocator)
2864: FirstBase(BSLS_COMPILERFEATURES_FORWARD(PARAM_1, a),
2865 basicAllocator,
2866 FirstBslmaIdiom())
2867, SecondBase(BSLS_COMPILERFEATURES_FORWARD(PARAM_2, b),
2868 basicAllocator,
2869 SecondBslmaIdiom())
2870{
2871}
2872#else
2873template <class T1, class T2>
2874template <class PARAM_1, class PARAM_2>
2875inline
2876pair<T1, T2>::pair(const PARAM_1& a,
2877 const PARAM_2& b,
2878 BloombergLP::bslma::Allocator *basicAllocator)
2879: FirstBase(a, basicAllocator, FirstBslmaIdiom())
2880, SecondBase(b, basicAllocator, SecondBslmaIdiom())
2881{
2882}
2883
2884template <class T1, class T2>
2885template <class PARAM_1, class PARAM_2>
2886inline
2888 const PARAM_2& b,
2889 BloombergLP::bslma::Allocator *basicAllocator)
2890: FirstBase(a, basicAllocator, FirstBslmaIdiom())
2891, SecondBase(b, basicAllocator, SecondBslmaIdiom())
2892{
2893}
2894
2895template <class T1, class T2>
2896template <class PARAM_1, class PARAM_2>
2897inline
2898pair<T1, T2>::pair(const PARAM_1& a,
2899 PARAM_2& b,
2900 BloombergLP::bslma::Allocator *basicAllocator)
2901: FirstBase(a, basicAllocator, FirstBslmaIdiom())
2902, SecondBase(b, basicAllocator, SecondBslmaIdiom())
2903{
2904}
2905
2906template <class T1, class T2>
2907template <class PARAM_1, class PARAM_2>
2908inline
2910 PARAM_2& b,
2911 BloombergLP::bslma::Allocator *basicAllocator)
2912: FirstBase(a, basicAllocator, FirstBslmaIdiom())
2913, SecondBase(b, basicAllocator, SecondBslmaIdiom())
2914{
2915}
2916#endif
2917
2918#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR) \
2919 && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE)
2920template <class T1, class T2>
2921template<class ...ARGS_1, class ...ARGS_2>
2922inline
2923pair<T1, T2>::pair(std::piecewise_construct_t,
2924 std::tuple<ARGS_1...> first_args,
2925 std::tuple<ARGS_2...> second_args)
2926: FirstBase(std::move(first_args),
2927 typename BloombergLP::bslstl::Pair_MakeIndexSequence<
2928 std::tuple_size<std::tuple<ARGS_1...> >::value
2929 >())
2930, SecondBase(std::move(second_args),
2931 typename BloombergLP::bslstl::Pair_MakeIndexSequence<
2932 std::tuple_size<std::tuple<ARGS_2...> >::value
2933 >())
2934{
2935}
2936
2937template <class T1, class T2>
2938template<class ...ARGS_1, class ...ARGS_2>
2939inline
2940pair<T1, T2>::pair(std::piecewise_construct_t,
2941 std::tuple<ARGS_1...> first_args,
2942 std::tuple<ARGS_2...> second_args,
2943 BloombergLP::bslma::Allocator *basicAllocator)
2944: FirstBase(Pair_ImpUtil::concatAllocator(std::move(first_args),
2945 basicAllocator,
2946 FirstBslmaIdiom()),
2947 typename BloombergLP::bslstl::Pair_MakeIndexSequence<
2948 Pair_ConstructionParametersPackLength<T1, ARGS_1...>::value>())
2949, SecondBase(Pair_ImpUtil::concatAllocator(std::move(second_args),
2950 basicAllocator,
2951 SecondBslmaIdiom()),
2952 typename BloombergLP::bslstl::Pair_MakeIndexSequence<
2953 Pair_ConstructionParametersPackLength<T2, ARGS_2...>::value>())
2954{
2955}
2956#endif
2957
2958template <class T1, class T2>
2959inline
2960pair<T1, T2>::pair(const pair& original,
2961 BloombergLP::bslma::Allocator *basicAllocator)
2962: FirstBase(original.first, basicAllocator, FirstBslmaIdiom())
2963, SecondBase(original.second, basicAllocator, SecondBslmaIdiom())
2964{
2965}
2966
2967#if defined (BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
2968template <class T1, class T2>
2969inline
2970pair<T1, T2>::pair(pair&& original,
2971 BloombergLP::bslma::Allocator *basicAllocator)
2972: FirstBase(BSLS_COMPILERFEATURES_FORWARD(T1, original.first),
2973 basicAllocator,
2974 FirstBslmaIdiom())
2975, SecondBase(BSLS_COMPILERFEATURES_FORWARD(T2, original.second),
2976 basicAllocator,
2977 SecondBslmaIdiom())
2978{
2979}
2980#else
2981template <class T1, class T2>
2982inline
2984pair<T1, T2>::pair(BloombergLP::bslmf::MovableRef<pair> original)
2985: FirstBase(MovUtil::move(MovUtil::access(original).first))
2986, SecondBase(MovUtil::move(MovUtil::access(original).second))
2987{
2988}
2989
2990template <class T1, class T2>
2991inline
2993pair<T1, T2>::pair(BloombergLP::bslmf::MovableRef<pair> original,
2994 BloombergLP::bslma::Allocator *basicAllocator)
2995: FirstBase(MovUtil::move(MovUtil::access(original).first),
2996 basicAllocator,
2998, SecondBase(MovUtil::move(MovUtil::access(original).second),
2999 basicAllocator,
3001{
3002}
3003#endif
3004
3005#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_BASELINE_LIBRARY)
3006template <class T1, class T2>
3007template <class PARAM_1, class PARAM_2>
3008inline
3011 const pair<PARAM_1, PARAM_2>& other,
3012 typename bsl::enable_if<
3013 std::is_constructible<T1, const PARAM_1&>::value &&
3014 std::is_constructible<T2, const PARAM_2&>::value,
3015 SfinaeEnable>::type)
3016: FirstBase(other.first)
3017, SecondBase(other.second)
3018{
3019}
3020
3021template <class T1, class T2>
3022template <class PARAM_1, class PARAM_2>
3023inline
3026 const std::pair<PARAM_1, PARAM_2>& other,
3027 typename bsl::enable_if<
3028 std::is_constructible<T1, const PARAM_1&>::value &&
3029 std::is_constructible<T2, const PARAM_2&>::value,
3030 SfinaeEnable>::type)
3031: FirstBase(other.first)
3032, SecondBase(other.second)
3033{
3034}
3035#else
3036template <class T1, class T2>
3037template <class PARAM_1, class PARAM_2>
3038inline
3041: FirstBase(other.first)
3042, SecondBase(other.second)
3043{
3044}
3045
3046template <class T1, class T2>
3047template <class PARAM_1, class PARAM_2>
3048inline
3050pair<T1, T2>::pair(const std::pair<PARAM_1, PARAM_2>& other)
3051: FirstBase(other.first)
3052, SecondBase(other.second)
3053{
3054}
3055#endif
3056
3057template <class T1, class T2>
3058template <class PARAM_1, class PARAM_2>
3059inline
3061 BloombergLP::bslma::Allocator *basicAllocator)
3062: FirstBase(other.first, basicAllocator, FirstBslmaIdiom())
3063, SecondBase(other.second, basicAllocator, SecondBslmaIdiom())
3064{
3065}
3066
3067template <class T1, class T2>
3068template <class PARAM_1, class PARAM_2>
3069inline
3070pair<T1, T2>::pair(const std::pair<PARAM_1, PARAM_2>& other,
3071 BloombergLP::bslma::Allocator *basicAllocator)
3072: FirstBase(other.first, basicAllocator, FirstBslmaIdiom())
3073, SecondBase(other.second, basicAllocator, SecondBslmaIdiom())
3074{
3075}
3076
3077#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
3078template <class T1, class T2>
3079template <class PARAM_1, class PARAM_2>
3081 pair<PARAM_1, PARAM_2>&& other,
3084 SfinaeEnable>::type)
3085: FirstBase(MovUtil::move(other.first))
3086, SecondBase(MovUtil::move(other.second))
3087{
3088}
3089
3090template <class T1, class T2>
3091template <class PARAM_1, class PARAM_2>
3093 std::pair<PARAM_1, PARAM_2>&& other,
3096 SfinaeEnable>::type)
3097: FirstBase(MovUtil::move(other.first))
3098, SecondBase(MovUtil::move(other.second))
3099{
3100}
3101
3102template <class T1, class T2>
3103template <class PARAM_1, class PARAM_2>
3104pair<T1, T2>::pair(pair<PARAM_1, PARAM_2>&& other,
3105 BloombergLP::bslma::Allocator *basicAllocator)
3106: FirstBase(MovUtil::move(other.first), basicAllocator, FirstBslmaIdiom())
3107, SecondBase(MovUtil::move(other.second), basicAllocator, SecondBslmaIdiom())
3108{
3109}
3110
3111template <class T1, class T2>
3112template <class PARAM_1, class PARAM_2>
3113pair<T1, T2>::pair(std::pair<PARAM_1, PARAM_2>&& other,
3114 BloombergLP::bslma::Allocator *basicAllocator)
3115: FirstBase(MovUtil::move(other.first), basicAllocator, FirstBslmaIdiom())
3116, SecondBase(MovUtil::move(other.second), basicAllocator, SecondBslmaIdiom())
3117{
3118}
3119#else
3120template <class T1, class T2>
3121template <class PARAM_1, class PARAM_2>
3123 BloombergLP::bslmf::MovableRef<pair<PARAM_1, PARAM_2> > other,
3124 BloombergLP::bslma::Allocator *basicAllocator)
3125: FirstBase(MovUtil::move(MovUtil::access(other).first),
3126 basicAllocator,
3128, SecondBase(MovUtil::move(MovUtil::access(other).second),
3129 basicAllocator,
3131{
3132}
3133
3134template <class T1, class T2>
3135template <class PARAM_1, class PARAM_2>
3137 BloombergLP::bslmf::MovableRef<std::pair<PARAM_1, PARAM_2> > other,
3138 BloombergLP::bslma::Allocator *basicAllocator)
3139: FirstBase(MovUtil::move(MovUtil::access(other).first),
3140 basicAllocator,
3142, SecondBase(MovUtil::move(MovUtil::access(other).second),
3143 basicAllocator,
3145{
3146}
3147#endif
3148
3149#ifndef BDE_OMIT_INTERNAL_DEPRECATED
3150template <class T1, class T2>
3151template <class PARAM_1, class PARAM_2>
3154 const BloombergLP::bslma::ManagedPtr_PairProxy<PARAM_1, PARAM_2>& rhs)
3155: FirstBase(rhs.first)
3156, SecondBase(rhs.second)
3157{
3158}
3159#endif // BDE_OMIT_INTERNAL_DEPRECATED
3160
3161// MANIPULATORS
3162#if !defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
3163template <class T1, class T2>
3164pair<T1, T2>& pair<T1, T2>::operator=(BloombergLP::bslmf::MovableRef<pair> rhs)
3166{
3167 pair& lvalue = rhs;
3168 first = MovUtil::move(lvalue.first);
3169 second = MovUtil::move(lvalue.second);
3170 return *this;
3171}
3172#endif
3173
3174template <class T1, class T2>
3175template <class PARAM_1, class PARAM_2>
3176inline
3178{
3179 first = rhs.first;
3180 second = rhs.second;
3181 return *this;
3182}
3183
3184#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
3185template <class T1, class T2>
3186template <class PARAM_1, class PARAM_2>
3188{
3189 first = MovUtil::move(rhs.first);
3190 second = MovUtil::move(rhs.second);
3191 return *this;
3192}
3193#else
3194template <class T1, class T2>
3195template <class PARAM_1, class PARAM_2>
3197 BloombergLP::bslmf::MovableRef<pair<PARAM_1, PARAM_2> > rhs)
3198{
3199 pair<PARAM_1, PARAM_2>& lvalue = rhs;
3200 first = MovUtil::move(lvalue.first);
3201 second = MovUtil::move(lvalue.second);
3202 return *this;
3203}
3204#endif
3205
3206template <class T1, class T2>
3207template <class PARAM_1, class PARAM_2>
3208inline
3210pair<T1, T2>::operator=(const std::pair<PARAM_1, PARAM_2>& rhs)
3211{
3212 first = rhs.first;
3213 second = rhs.second;
3214 return *this;
3215}
3216
3217#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE)
3218template <class T1, class T2>
3219template <class PARAM_1, class PARAM_2,
3222 bool>::type>
3223inline
3224pair<T1, T2>::operator std::tuple<PARAM_1&, PARAM_2&>() BSLS_KEYWORD_NOEXCEPT
3225{
3226 return std::tuple<PARAM_1&, PARAM_2&>(first, second);
3227}
3228
3229template <class T1, class T2>
3230template <class PARAM_1,
3232 bool>::type>
3233inline
3234pair<T1, T2>::operator std::tuple<PARAM_1&, decltype(std::ignore)&>()
3236{
3237 return std::tuple<PARAM_1&, decltype(std::ignore)&>(first, std::ignore);
3238}
3239
3240template <class T1, class T2>
3241template <class PARAM_2,
3243 bool>::type>
3244inline
3245pair<T1, T2>::operator std::tuple<decltype(std::ignore)&, PARAM_2&>()
3247{
3248 return std::tuple<decltype(std::ignore)&, PARAM_2&>(std::ignore, second);
3249}
3250#endif
3251
3252
3253template <class T1, class T2>
3254inline
3255#if defined(BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE)
3256void pair<T1, T2>::swap(pair& other)
3257 BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(Pair_ImpUtil::hasNothrowSwap<T1, T2>())
3258#else
3259void pair<T1, T2>::swap(pair& other)
3260 BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(bsl::is_nothrow_swappable<T1>::value
3261 && bsl::is_nothrow_swappable<T2>::value)
3262#endif
3263{
3264 // Find either 'std::swap' or a specialized 'swap' for 'T1' and 'T2' via
3265 // ADL.
3266
3267 using std::swap;
3268
3269 swap(first, other.first);
3270 swap(second, other.second);
3271}
3272
3273// FREE OPERATORS
3274template <class T1, class T2>
3275inline
3277bool operator==(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs)
3278{
3279 return lhs.first == rhs.first && lhs.second == rhs.second;
3280}
3281
3282#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
3283template <class T1, class T2>
3284inline
3286bool operator!=(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs)
3287{
3288 return ! (lhs == rhs);
3289}
3290#endif
3291
3292#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
3293
3294template <class T1, class T2>
3296std::common_comparison_category_t<
3297 BloombergLP::bslalg::SynthThreeWayUtil::Result<T1>,
3298 BloombergLP::bslalg::SynthThreeWayUtil::Result<T2>
3299> operator<=>(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs)
3300{
3301 using BloombergLP::bslalg::SynthThreeWayUtil;
3302 auto result = SynthThreeWayUtil::compare(lhs.first, rhs.first);
3303 return result == 0 ? SynthThreeWayUtil::compare(lhs.second, rhs.second)
3304 : result;
3305}
3306
3307#else
3308
3309template <class T1, class T2>
3310inline
3312bool operator<(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs)
3313{
3314 return (lhs.first < rhs.first ? true :
3315 rhs.first < lhs.first ? false :
3316 lhs.second < rhs.second);
3317}
3318
3319template <class T1, class T2>
3320inline
3322bool operator>(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs)
3323{
3324 return rhs < lhs;
3325}
3326
3327template <class T1, class T2>
3328inline
3330bool operator<=(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs)
3331{
3332 return ! (rhs < lhs);
3333}
3334
3335template <class T1, class T2>
3336inline
3338bool operator>=(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs)
3339{
3340 return ! (lhs < rhs);
3341}
3342
3343#endif // BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
3344
3345// FREE FUNCTIONS
3346template <class T1, class T2>
3347inline
3348#if defined(BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE)
3349void
3350#else
3352 && bsl::is_swappable<T2>::value>::type
3353#endif
3355 BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(noexcept(a.swap(b)))
3356{
3357 a.swap(b);
3358}
3359
3360// HASH SPECIALIZATIONS
3361template <class HASHALG, class T1, class T2>
3362void hashAppend(HASHALG& hashAlg, const pair<T1, T2>& input)
3363{
3364 using ::BloombergLP::bslh::hashAppend;
3365 hashAppend(hashAlg, input.first);
3366 hashAppend(hashAlg, input.second);
3367}
3368
3369} // close namespace bsl
3370
3371#if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE)
3372
3373namespace bslstl {
3374
3375 // ---------------------
3376 // class Pair_GetImpUtil
3377 // ---------------------
3378
3379// CLASS METHODS
3380template <class T1, class T2>
3381inline
3382T1& Pair_GetImpUtil<0, T1, T2>::getPairElement(bsl::pair<T1, T2>& p)
3384{
3385 return p.first;
3386}
3387
3388template <class T1, class T2>
3389inline
3390const T1&
3391Pair_GetImpUtil<0, T1, T2>::getPairElement(const bsl::pair<T1, T2>& p)
3393{
3394 return p.first;
3395}
3396
3397#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
3398template <class T1, class T2>
3399inline
3400T1&& Pair_GetImpUtil<0, T1, T2>::getPairElement(bsl::pair<T1, T2>&& p)
3402{
3403 return std::move(p.first);
3404}
3405
3406template <class T1, class T2>
3407inline
3408const T1&&
3409Pair_GetImpUtil<0, T1, T2>::getPairElement(const bsl::pair<T1, T2>&& p)
3411{
3412 return std::move(p.first);
3413}
3414#endif
3415
3416template <class T1, class T2>
3417inline
3418T2& Pair_GetImpUtil<1u, T1, T2>::getPairElement(bsl::pair<T1, T2>& p)
3420{
3421 return p.second;
3422}
3423
3424template <class T1, class T2>
3425inline
3426const T2&
3427Pair_GetImpUtil<1u, T1, T2>::getPairElement(const bsl::pair<T1, T2>& p)
3429{
3430 return p.second;
3431}
3432
3433#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
3434template <class T1, class T2>
3435inline
3436T2&& Pair_GetImpUtil<1u, T1, T2>::getPairElement(bsl::pair<T1, T2>&& p)
3438{
3439 return std::move(p.second);
3440}
3441
3442template <class T1, class T2>
3443inline
3444const T2&&
3445Pair_GetImpUtil<1u, T1, T2>::getPairElement(const bsl::pair<T1, T2>&& p)
3447{
3448 return std::move(p.second);
3449}
3450
3451#endif
3452
3453} // close package namespace
3454
3455
3456// FREE FUNCTIONS
3457template<std::size_t INDEX, class T1, class T2>
3458inline
3459typename std::tuple_element<INDEX, bsl::pair<T1, T2> >::type&
3461{
3462 return BloombergLP::bslstl::Pair_GetImpUtil<INDEX, T1, T2>::getPairElement(
3463 p);
3464}
3465
3466template<std::size_t INDEX, class T1, class T2>
3467inline
3468const typename std::tuple_element<INDEX, bsl::pair<T1, T2> >::type&
3470{
3471 return BloombergLP::bslstl::Pair_GetImpUtil<INDEX, T1, T2>::getPairElement(
3472 p);
3473}
3474
3475#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
3476template<std::size_t INDEX, class T1, class T2>
3477inline
3478typename std::tuple_element<INDEX, bsl::pair<T1, T2> >::type&&
3480{
3481 return BloombergLP::bslstl::Pair_GetImpUtil<INDEX, T1, T2>::getPairElement(
3482 std::move(p));
3483}
3484#endif
3485
3486template<class TYPE, class T1, class T2>
3487inline
3489{
3490 return BloombergLP::bslstl::Pair_GetImpUtil<
3491 BloombergLP::bslstl::Pair_IndexOfType<TYPE, T1, T2>::value, T1, T2>
3492 ::getPairElement(p);
3493}
3494
3495template<class TYPE, class T1, class T2>
3496inline
3498{
3499 return BloombergLP::bslstl::Pair_GetImpUtil<
3500 BloombergLP::bslstl::Pair_IndexOfType<TYPE, T1, T2>::value, T1, T2>
3501 ::getPairElement(p);
3502}
3503
3504#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
3505template<class TYPE, class T1, class T2>
3506inline
3508{
3509 return BloombergLP::bslstl::Pair_GetImpUtil<
3510 BloombergLP::bslstl::Pair_IndexOfType<TYPE, T1, T2>::value, T1, T2>
3511 ::getPairElement(std::move(p));
3512}
3513
3514template<class TYPE, class T1, class T2>
3515inline
3516const TYPE&& bsl::get(const bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT
3517{
3518 return BloombergLP::bslstl::Pair_GetImpUtil<
3519 BloombergLP::bslstl::Pair_IndexOfType<TYPE, T1, T2>::value, T1, T2>
3520 ::getPairElement(std::move(p));
3521}
3522#endif // BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
3523
3524#endif // BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE
3525
3526// ============================================================================
3527// TYPE TRAITS
3528// ============================================================================
3529
3530namespace bsl {
3531
3532template <class T1, class T2>
3534 : bsl::integral_constant<bool, is_trivially_copyable<T1>::value
3535 && is_trivially_copyable<T2>::value>
3536{};
3537
3538template <class T1, class T2>
3540: bsl::integral_constant<bool, is_trivially_default_constructible<T1>::value
3541 && is_trivially_default_constructible<T2>::value>
3542{};
3543
3544} // close namespace bsl
3545
3546
3547namespace bslmf {
3548
3549template <class T1, class T2>
3550struct IsBitwiseCopyable<bsl::pair<T1, T2> >
3551 : bsl::integral_constant<bool, IsBitwiseCopyable<T1>::value
3552 && IsBitwiseCopyable<T2>::value>
3553{};
3554
3555template <class T1, class T2>
3556struct IsPair<bsl::pair<T1, T2> > : bsl::true_type
3557{};
3558
3559// Note that we must explicitly declare bitwise moveable sine 'T1' or 'T2' may
3560// be bitwise moveable and not bitwise copyable.
3561
3562template <class T1, class T2>
3563struct IsBitwiseMoveable<bsl::pair<T1, T2> >
3564 : bsl::integral_constant<bool, bslmf::IsBitwiseMoveable<T1>::value
3565 && bslmf::IsBitwiseMoveable<T2>::value>
3566{};
3567
3568template <class T1, class T2>
3569struct IsBitwiseEqualityComparable<bsl::pair<T1, T2> >
3570: bsl::integral_constant<bool, bslmf::IsBitwiseEqualityComparable<T1>::value
3571 && bslmf::IsBitwiseEqualityComparable<T2>::value
3572 && sizeof(T1) + sizeof(T2) ==
3573 sizeof(bsl::pair<T1, T2>)>
3574{};
3575
3576} // close namespace bslmf
3577
3578namespace bslma {
3579
3580template <class T1, class T2>
3581struct UsesBslmaAllocator<bsl::pair<T1, T2> >
3582 : bsl::integral_constant<bool, UsesBslmaAllocator<T1>::value
3583 || UsesBslmaAllocator<T2>::value>
3584{};
3585
3586} // close namespace bslma
3587
3588
3589
3590#ifdef BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE
3591#undef BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE
3592#endif
3593
3594#endif
3595
3596// ----------------------------------------------------------------------------
3597// Copyright 2013 Bloomberg Finance L.P.
3598//
3599// Licensed under the Apache License, Version 2.0 (the "License");
3600// you may not use this file except in compliance with the License.
3601// You may obtain a copy of the License at
3602//
3603// http://www.apache.org/licenses/LICENSE-2.0
3604//
3605// Unless required by applicable law or agreed to in writing, software
3606// distributed under the License is distributed on an "AS IS" BASIS,
3607// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3608// See the License for the specific language governing permissions and
3609// limitations under the License.
3610// ----------------------------- END-OF-FILE ----------------------------------
3611
3612/** @} */
3613/** @} */
3614/** @} */
Definition bslstl_pair.h:1210
pair & operator=(const std::pair< PARAM_1, PARAM_2 > &rhs)
BSLS_KEYWORD_CONSTEXPR pair(BloombergLP::bslmf::MovableRef< pair< PARAM_1, PARAM_2 > > other, typename bsl::enable_if< bsl::is_convertible< PARAM_1, T1 >::value &&bsl::is_convertible< PARAM_2, T2 >::value, SfinaeEnable >::type=SfinaeEnable())
Definition bslstl_pair.h:1493
pair(const PARAM_1 &a, PARAM_2 &b, BloombergLP::bslma::Allocator *basicAllocator)
Definition bslstl_pair.h:2898
pair(BloombergLP::bslmf::MovableRef< std::pair< PARAM_1, PARAM_2 > > other, BloombergLP::bslma::Allocator *basicAllocator)
Definition bslstl_pair.h:3136
pair(typename bsl::add_lvalue_reference< const T1 >::type a, typename bsl::add_lvalue_reference< const T2 >::type b, BloombergLP::bslma::Allocator *basicAllocator)
Definition bslstl_pair.h:2848
pair(const PARAM_1 &a, const PARAM_2 &b, BloombergLP::bslma::Allocator *basicAllocator)
Definition bslstl_pair.h:2876
BSLS_KEYWORD_CONSTEXPR pair(BloombergLP::bslmf::MovableRef< std::pair< PARAM_1, PARAM_2 > > other, typename bsl::enable_if< bsl::is_convertible< PARAM_1, T1 >::value &&bsl::is_convertible< PARAM_2, T2 >::value, SfinaeEnable >::type=SfinaeEnable())
Definition bslstl_pair.h:1508
T1 first_type
Definition bslstl_pair.h:1231
BSLS_KEYWORD_CONSTEXPR pair(const std::pair< PARAM_1, PARAM_2 > &other, typename bsl::enable_if< std::is_constructible< T1, const PARAM_1 & >::value &&std::is_constructible< T2, const PARAM_2 & >::value, SfinaeEnable >::type=SfinaeEnable())
Definition bslstl_pair.h:3025
pair(BloombergLP::bslma::Allocator *basicAllocator)
Definition bslstl_pair.h:2830
BSLS_KEYWORD_CONSTEXPR pair(const BloombergLP::bslma::ManagedPtr_PairProxy< PARAM_1, PARAM_2 > &rhs)
Definition bslstl_pair.h:3153
pair & operator=(const pair< PARAM_1, PARAM_2 > &rhs)
pair(BloombergLP::bslmf::MovableRef< pair< PARAM_1, PARAM_2 > > other, BloombergLP::bslma::Allocator *basicAllocator)
Definition bslstl_pair.h:3122
pair(PARAM_1 &a, const PARAM_2 &b, BloombergLP::bslma::Allocator *basicAllocator)
Definition bslstl_pair.h:2887
BSLS_KEYWORD_CONSTEXPR pair(BloombergLP::bslmf::MovableRef< pair > original)
Definition bslstl_pair.h:2984
~pair()=default
BSLS_KEYWORD_CONSTEXPR pair(const PARAM_1 &a, PARAM_2 &b, typename bsl::enable_if< bsl::is_convertible< PARAM_1, T1 >::value &&bsl::is_convertible< PARAM_2, T2 >::value &&!(bsl::is_pointer< typename bsl::remove_reference< PARAM_2 >::type >::value &&bsl::is_convertible< PARAM_2, BloombergLP::bslma::Allocator * >::value), SfinaeEnable >::type=SfinaeEnable())
Definition bslstl_pair.h:1371
BSLS_KEYWORD_CONSTEXPR pair(const PARAM_1 &a, const PARAM_2 &b, typename bsl::enable_if< bsl::is_convertible< PARAM_1, T1 >::value &&bsl::is_convertible< PARAM_2, T2 >::value &&!(bsl::is_pointer< typename bsl::remove_reference< PARAM_2 >::type >::value &&bsl::is_convertible< PARAM_2, BloombergLP::bslma::Allocator * >::value), SfinaeEnable >::type=SfinaeEnable())
Definition bslstl_pair.h:1323
pair(BloombergLP::bslmf::MovableRef< pair > original, BloombergLP::bslma::Allocator *basicAllocator)
Definition bslstl_pair.h:2993
BSLS_KEYWORD_CONSTEXPR pair(typename bsl::add_lvalue_reference< const T1 >::type a, typename bsl::add_lvalue_reference< const T2 >::type b)
Definition bslstl_pair.h:2839
BSLS_KEYWORD_CONSTEXPR pair(PARAM_1 &a, const PARAM_2 &b, typename bsl::enable_if< bsl::is_convertible< PARAM_1, T1 >::value &&bsl::is_convertible< PARAM_2, T2 >::value &&!(bsl::is_pointer< typename bsl::remove_reference< PARAM_2 >::type >::value &&bsl::is_convertible< PARAM_2, BloombergLP::bslma::Allocator * >::value), SfinaeEnable >::type=SfinaeEnable())
Definition bslstl_pair.h:1347
pair(const pair< PARAM_1, PARAM_2 > &other, BloombergLP::bslma::Allocator *basicAllocator)
Definition bslstl_pair.h:3060
pair(const std::pair< PARAM_1, PARAM_2 > &other, BloombergLP::bslma::Allocator *basicAllocator)
Definition bslstl_pair.h:3070
T2 second_type
Definition bslstl_pair.h:1232
pair(const pair &original, BloombergLP::bslma::Allocator *basicAllocator)
Definition bslstl_pair.h:2960
pair & operator=(BloombergLP::bslmf::MovableRef< pair > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(false)
Definition bslstl_pair.h:3164
BSLS_KEYWORD_CONSTEXPR pair(const pair< PARAM_1, PARAM_2 > &other, typename bsl::enable_if< std::is_constructible< T1, const PARAM_1 & >::value &&std::is_constructible< T2, const PARAM_2 & >::value, SfinaeEnable >::type=SfinaeEnable())
Definition bslstl_pair.h:3010
BSLS_KEYWORD_CONSTEXPR pair()
Definition bslstl_pair.h:2821
pair(PARAM_1 &a, PARAM_2 &b, BloombergLP::bslma::Allocator *basicAllocator)
Definition bslstl_pair.h:2909
BSLS_KEYWORD_CONSTEXPR pair(PARAM_1 &a, PARAM_2 &b, typename bsl::enable_if< bsl::is_convertible< PARAM_1, T1 >::value &&bsl::is_convertible< PARAM_2, T2 >::value &&!(bsl::is_pointer< typename bsl::remove_reference< PARAM_2 >::type >::value &&bsl::is_convertible< PARAM_2, BloombergLP::bslma::Allocator * >::value), SfinaeEnable >::type=SfinaeEnable())
Definition bslstl_pair.h:1395
pair & operator=(BloombergLP::bslmf::MovableRef< pair< PARAM_1, PARAM_2 > > rhs)
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:229
#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_OPERATOR(...)
Definition bsls_keyword.h:635
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:588
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:634
void swap(OptionValue &a, OptionValue &b)
Definition bdlb_printmethods.h:283
void hashAppend(HASH_ALGORITHM &hashAlgorithm, const array< TYPE, SIZE > &input)
Pass the specified input to the specified hashAlgorithm
Definition bslstl_array.h:950
BSLS_KEYWORD_CONSTEXPR_CPP14 TYPE & get(array< TYPE, SIZE > &a) BSLS_KEYWORD_NOEXCEPT
bsl::integral_constant< int, 0 > Pair_BslmaIdiomNone
Definition bslstl_pair.h:460
bsl::integral_constant< int, 2 > Pair_BslmaIdiomAllocatorArgT
Definition bslstl_pair.h:469
bsl::integral_constant< int, 1 > Pair_BslmaIdiomAtEnd
Definition bslstl_pair.h:464
Definition balxml_encoderoptions.h:68
Definition bdlbb_blob.h:576
Definition bslstl_algorithm.h:82
Definition bdldfp_decimal.h:5188
void swap(TYPE &a, TYPE &b)
Definition bslstl_pair.h:486
TYPE & first
Definition bslstl_pair.h:748
Definition bslstl_pair.h:587
Pair_First & operator=(Pair_First &&)=default
Pair_First(const Pair_First &)=default
BSLS_KEYWORD_CONSTEXPR Pair_First(PARAM &value)
Definition bslstl_pair.h:2193
Pair_First(const PARAM &value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT)
Definition bslstl_pair.h:2275
Pair_First(PARAM &value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT)
Definition bslstl_pair.h:2285
Pair_First(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT)
Definition bslstl_pair.h:2149
Pair_First(PARAM &value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd)
Definition bslstl_pair.h:2265
Pair_First(PARAM &value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone)
Definition bslstl_pair.h:2245
Pair_First(Pair_First &&)=default
BSLS_KEYWORD_CONSTEXPR Pair_First(const PARAM &value)
Definition bslstl_pair.h:2184
BSLS_KEYWORD_CONSTEXPR Pair_First(typename bsl::add_lvalue_reference< const TYPE >::type value)
Definition bslstl_pair.h:2158
Pair_First(const PARAM &value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone)
Definition bslstl_pair.h:2235
~Pair_First()=default
Pair_First(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd)
Definition bslstl_pair.h:2141
BSLS_KEYWORD_CONSTEXPR Pair_First()
Definition bslstl_pair.h:2125
Pair_First(const PARAM &value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd)
Definition bslstl_pair.h:2255
TYPE first
Definition bslstl_pair.h:605
Pair_First(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone)
Definition bslstl_pair.h:2133
Definition bslstl_pair.h:506
TYPE & second
Definition bslstl_pair.h:1050
Definition bslstl_pair.h:891
Pair_Second(PARAM &value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT)
Definition bslstl_pair.h:2635
BSLS_KEYWORD_CONSTEXPR Pair_Second()
Definition bslstl_pair.h:2476
Pair_Second(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd)
Definition bslstl_pair.h:2492
Pair_Second(const PARAM &value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT)
Definition bslstl_pair.h:2625
Pair_Second(const PARAM &value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd)
Definition bslstl_pair.h:2605
Pair_Second(PARAM &value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd)
Definition bslstl_pair.h:2615
Pair_Second(Pair_Second &&)=default
TYPE second
Definition bslstl_pair.h:908
Pair_Second(PARAM &value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone)
Definition bslstl_pair.h:2595
BSLS_KEYWORD_CONSTEXPR Pair_Second(PARAM &value)
Definition bslstl_pair.h:2543
Pair_Second(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT)
Definition bslstl_pair.h:2500
Pair_Second(const PARAM &value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone)
Definition bslstl_pair.h:2585
Pair_Second(const Pair_Second &)=default
BSLS_KEYWORD_CONSTEXPR Pair_Second(const PARAM &value)
Definition bslstl_pair.h:2535
Pair_Second(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone)
Definition bslstl_pair.h:2484
Pair_Second & operator=(Pair_Second &&)=default
~Pair_Second()=default
BSLS_KEYWORD_CONSTEXPR Pair_Second(typename bsl::add_lvalue_reference< const TYPE >::type value)
Definition bslstl_pair.h:2509
t_TYPE & type
This typedef defines the return type of this meta function.
Definition bslmf_addlvaluereference.h:129
Definition bslmf_enableif.h:525
Definition bslmf_integralconstant.h:244
Definition bslmf_isconvertible.h:867
Definition bslmf_ispointer.h:138
Definition bslmf_istriviallycopyable.h:329
Definition bslmf_istriviallydefaultconstructible.h:293
Definition bslma_usesbslmaallocator.h:343
Definition bslmf_isbitwisecopyable.h:298
Definition bslmf_isbitwiseequalitycomparable.h:499
Definition bslmf_isbitwisemoveable.h:718
Definition bslmf_ispair.h:88
Definition bslmf_movableref.h:791