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