// bslstl_pair.h -*-C++-*- #ifndef INCLUDED_BSLSTL_PAIR #define INCLUDED_BSLSTL_PAIR #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a simple 'struct' with two members that may use allocators. // //@CLASSES: // bsl::pair: pair of values, each of which may use a 'bslma::Allocator' // //@CANONICAL_HEADER: bsl_utility.h // //@DESCRIPTION: 'bsl::pair' is an allocator-aware version of 'std::pair'. // The 'bsl::pair' class template is instantiated on two types, 'T1' and 'T2', // and provides two public data members, 'first' and 'second' of types 'T1' and // 'T2', respectively. Each data member might or might not allocate memory // using 'bslma::Allocator'. Its interface is identical to 'std::pair' except // that it has constructors that take optional allocator arguments to correctly // construct the member variables. For example, a // 'bsl::pair<std::string, int>' has member 'first' of type 'std::string' and // 'second' of type 'int'. A client can pass a 'bslma::Allocator' pointer to // the pair constructor and the constructor will pass it through to the 'first' // member. Similarly, the copy constructor takes an optional // 'bslma::Allocator' pointer and copy-constructs the 'first' member using that // allocator. // // 'bsl::pair' is unusual in that its data members, 'first' and 'second', are // public. Once constructed, a client program accesses these members directly. // This part of the interface is identical to 'std::pair', for which // 'bsl::pair' is intended to be a drop-in replacement. // // 'bsl::pair' has four constructors: a default constructor that // default-constructs the two data members, a copy constructor that // copy-constructs each data member, a constructor taking two arguments of type // 'T1' and 'T2', which are used to copy-construct 'first' and 'second' // respectively, and a conversion constructor template for converting from a // 'bsl::pair' of different types, 'PARAM_1' and 'PARAM_2', provided 'PARAM_1' // is convertible to 'T1' and 'PARAM_2' is convertible to 'T2'. Each // constructor also has an optional 'bslma::Allocator' pointer argument. If // neither 'T1' nor 'T2' use 'bslma::Allocator', this argument is ignored. // Otherwise, either 'first' or 'second', or both, depending on whether each // type uses 'bslma::Allocator', will be passed the 'bslma::Allocator*' // argument during construction. Whether or not a type uses 'bslma::Allocator' // is determined by querying the 'bslma::UsesBslmaAllocator' trait for that // type. This component also defines a full set of equality and relational // operators that can be instantiated if 'T1' and 'T2' both provide those // operators. // // A 'bsl::pair' declares a set of associated type traits that are computed // from the type traits of 'T1' and 'T2'. For each supported type trait, a // given specialization of 'bsl::pair' has that trait if and only if *both* // 'T1' and 'T2' have that trait. Supported traits are: //.. // bslmf::IsBitwiseMoveable // bslmf::IsBitwiseEqualityComparable // bsl::is_trivially_copyable // bsl::is_trivially_default_constructible //.. // In addition, a 'bsl::pair' specialization has the // 'bslma::UsesBslmaAllocator' trait if *either* 'T1' or 'T2' have that trait, // or both. // ///Enhancements Enabled by Modern Language Standards ///------------------------------------------------- // Language standards after the first (C++98) and its corrigendum (C++03) have // added code C++ language features, type traits as well as requirements that // affect the exact interface 'pair' provides. This section describes such // enhancements as they become available. // ///Conditional Default Constructor (C++11) ///- - - - - - - - - - - - - - - - - - - - // C++11 has introduced type traits, many of which needs compiler backing to be // (automatically implementable) and also introduced "defaulted" (special // member) functions that generate code without making mistakes. Before C++11 // it was not possible to determine if a type had a default constructor in a // non-intrusive manner. C++11 makes it possible using <type_traits> to // determine that, and '= default' makes it possible to create special member // functions that exists only when they can be implemented properly. // // Hence, when using compilers with a reasonably complete implementation of // C++11 (notably MSVC 2013 is not one of those) we only implement the default // constructor of pair if both types inside the pair type have a default // constructor. Note that it means that when using C++11 (except in compilers // not implementing it properly) a 'bsl::pair' that stores a reference type // (such as 'int&'), or any other type that cannot be default constructed using // the syntax 'T v{};' will cause pair to neither declare nor define a default // constructor. So from C++11 onwards a type of 'bsl::pair<T1, T2>' will have // a default constructor only if both types 'T1' and 'T2' are default // constructible. Otherwise, pair will have a default constructor that gives a // compile-error (only) if called. // ///Usage ///----- // A 'bsl::pair' is a very simple object when used without allocators. Our // usage example concentrates on the use of allocators with 'bsl::pair'. // First, we create a utility function that copies a null-terminated string // into memory allocated from a supplied allocator: //.. // char *myStrDup(const char *s, bslma::Allocator *basicAllocator) // // Copy the specified null-terminated string 's' into memory allocated // // from the specified 'basicAllocator' // { // char *result = (char*) basicAllocator->allocate(std::strlen(s) + 1); // return std::strcpy(result, s); // } //.. // We create a simple string class that holds strings allocated from a supplied // allocator. It uses 'myStrDup' (above) in its implementation: //.. // class my_String { // // Simple string class that uses a 'bslma::Allocator' allocator. // // bslma::Allocator *d_allocator_p; // char *d_data; // // public: // BSLMF_NESTED_TRAIT_DECLARATION(my_String, bslma::UsesBslmaAllocator); // // explicit my_String(bslma::Allocator *basicAllocator = 0); // // Construct an empty string using the optionally-specified // // allocator 'basicAllocator'. // // my_String(const char* s, bslma::Allocator *alloc = 0); // IMPLICIT // // Construct a string with contents specified in 's' using the // // optionally-specified allocator 'basicAllocator'. // // my_String(const my_String& rhs, bslma::Allocator *alloc = 0); // // Construct a copy of the specified 'rhs' string using the // // optionally-specified allocator 'basicAllocator'. // // ~my_String(); // // Destroy this string. // // my_String& operator=(const my_String& rhs); // // Copy specified 'rhs' string value to this string. // // const char* c_str() const; // // Return the null-terminated character array for this string. // // bslma::Allocator *allocator() const; // // Return the allocator used to construct this string or, if no // // allocator was specified at construction, the default allocator // // at the time of construction. // }; // // bool operator==(const my_String& str1, const my_String& str2) // { // return 0 == std::strcmp(str1.c_str(), str2.c_str()); // } // // bool operator==(const my_String& str, const char *p) // { // return 0 == std::strcmp(p, str.c_str()); // } // // bool operator==(const char *p, const my_String& str) // { // return str == p; // } // // bool operator!=(const my_String& str1, const my_String& str2) // { // return ! (str1 == str2); // } // // bool operator!=(const my_String& str, const char *p) // { // return ! (str == p); // } // // bool operator!=(const char *p, const my_String& str) // { // return ! (str == p); // } // // bool operator<(const my_String& str1, const my_String& str2) // { // return std::strcmp(str1.c_str(), str2.c_str()) < 0; // } // // my_String::my_String(bslma::Allocator *basicAllocator) // : d_allocator_p(bslma::Default::allocator(basicAllocator)), d_data(0) // { // d_data = myStrDup("", d_allocator_p); // } // // my_String::my_String(const char *s, bslma::Allocator *basicAllocator) // : d_allocator_p(bslma::Default::allocator(basicAllocator)), d_data(0) // { // d_data = myStrDup(s, d_allocator_p); // } // // my_String::my_String(const my_String& rhs, // bslma::Allocator *basicAllocator) // : d_allocator_p(bslma::Default::allocator(basicAllocator)), d_data(0) // { // d_data = myStrDup(rhs.d_data, d_allocator_p); // } // // my_String::~my_String() // { // d_allocator_p->deallocate(d_data); // } // // my_String& my_String::operator=(const my_String& rhs) // { // if (this != &rhs) { // d_allocator_p->deallocate(d_data); // d_data = myStrDup(rhs.d_data, d_allocator_p); // } // return *this; // } // // const char *my_String::c_str() const // { // return d_data; // } // // bslma::Allocator *my_String::allocator() const // { // return d_allocator_p; // } //.. // Our main program creates a mapping from strings to integers. Each node of // the mapping consists of a 'bsl::pair<my_String, int>'. The program // allocates memory from a test allocator in order to ensure that there are no // leaks: //.. // int main() // { // typedef bsl::pair<my_String, int> Node; // // Node *mapping[3]; // bslma::TestAllocator alloc; //.. // When constructing a 'Node', an allocator is supplied in addition to // parameters for the 'first' and 'second' data members. //.. // { // mapping[0] = new(basicAllocator) Node("One", 1, &basicAllocator); // mapping[1] = new(basicAllocator) Node("Three", 3, &basicAllocator); // mapping[2] = new(basicAllocator) Node("Two", 2, &basicAllocator); // // Temporaries get destroyed here, even on broken compilers. // } // // assert("One" == mapping[0]->first); // assert(1 == mapping[0]->second); // assert("Three" == mapping[1]->first); // assert(3 == mapping[1]->second); // assert("Two" == mapping[2]->first); // assert(2 == mapping[2]->second); // // assert(6 == alloc.numBlocksInUse()); //.. // Clean up at end. //.. // alloc.deleteObjectRaw(mapping[0]); // alloc.deleteObjectRaw(mapping[1]); // alloc.deleteObjectRaw(mapping[2]); // // assert(0 == alloc.numBlocksInUse()); // // return 0; // } //.. #include <bslscm_version.h> #include <bslstl_hash.h> #include <bslh_hash.h> #include <bslma_allocator.h> #ifndef BDE_OMIT_INTERNAL_DEPRECATED #include <bslma_managedptr_pairproxy.h> #endif // BDE_OMIT_INTERNAL_DEPRECATED #include <bslma_usesbslmaallocator.h> #include <bslmf_addlvaluereference.h> #include <bslmf_allocatorargt.h> #include <bslmf_conditional.h> #include <bslmf_integersequence.h> #include <bslmf_isbitwiseequalitycomparable.h> #include <bslmf_isbitwisemoveable.h> #include <bslmf_isconvertible.h> #include <bslmf_isnothrowswappable.h> #include <bslmf_ispair.h> #include <bslmf_isswappable.h> #include <bslmf_istriviallycopyable.h> #include <bslmf_istriviallydefaultconstructible.h> #include <bslmf_makeintegersequence.h> #include <bslmf_movableref.h> #include <bslmf_usesallocatorargt.h> #include <bslmf_util.h> #include <bsls_compilerfeatures.h> #include <bsls_keyword.h> #include <bsls_libraryfeatures.h> #include <bsls_platform.h> #include <bsls_util.h> // 'forward<T>(V)' #include <cstddef> // 'std::size_t' #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) # include <tuple> // 'std::tuple' #endif #include <utility> // 'std::pair' and (in C++11 mode) 'std::swap' #ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES #include <bsls_nativestd.h> #endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES #if !defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) \ && !defined(BSLS_PLATFORM_CMP_CLANG) // If the compiler supports rvalue references, then we have C++11 'std::swap', // which has a complicated SFINAE clause. Fortunately, it is defined in // <utility>, which is included. // // However, if the compiler does not support rvalue references, then we have // C++03 'std::swap', which has a trivial signature. We forward-declare it // here because otherwise we'd have to '#include <algorithm>', which causes // difficult-to-fix cyclic dependencies between the native library and bsl. #ifdef std # error This header should not be #included with 'std' being a macro #endif #if !defined(BSLS_PLATFORM_CMP_SUN) \ || !defined(BSLS_COMPILERFEATURES_SUPPORT_NOEXCEPT) namespace std { template <class TYPE> void swap(TYPE& a, TYPE& b); } // close namespace std #endif #endif // ! BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES && ! CLANG #if !defined(BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS) \ || (defined(BSLS_PLATFORM_CMP_MSVC) && BSLS_PLATFORM_CMP_VERSION < 1900) # define BSLSTL_PAIR_NO_IMPLICIT_DELETED_FOR_MOVE_OPS 1 // In order to support the correct signature for copy constructor/assignment // operators of members with non-'const' references for those operations, we // must take the implicitly generated declarations. However, the specification // for assignment through references requires defining the assignment operator // in those cases, and that will delete any (otherwise) implicitly-declared // constructors, so they must be explicitly defaulted on platforms that support // them. However, Visual C++ 2013 refused to recognize these defaults as valid // for move constructors, so a special exception must be made in this case. #endif #if !defined(BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS) || \ !defined(BSLS_COMPILERFEATURES_SUPPORT_DEFAULT_TEMPLATE_ARGS) || \ (defined(BSLS_PLATFORM_CMP_MSVC) && BSLS_PLATFORM_CMP_VERSION < 1900) // MSVC 2013 implicitly declared and defines a default constructor, even for // members that are not default constructible such as references. #define BSLSTL_PAIR_DO_NOT_DEFAULT_THE_DEFAULT_CONSTRUCTOR 1 #endif #if defined(BSLS_PLATFORM_CMP_MSVC) #if (BSLS_COMPILERFEATURES_CPLUSPLUS < 201703L || \ BSLS_PLATFORM_CMP_VERSION <= 1916) // MSVC 2017 and earlier, as well as later versions of MSVC compiling against // pre-C++17 standards, are unable to perform the required template argument // deductions to enable the use of 'bsl::is_swappable' within the SFINAE test // for 'swap()'. In this case we must fall back on the previous, pre-C++17 // implementation which simply assumes swappability. #define BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE 1 #endif #endif #if !defined(BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE) // When compiling without 'decltype' support, 'bsl::is_swappable' is not // defined. In this case we must fall back on the previous, pre-C++17 // implementation which simply assumes swappability. #define BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE 1 #endif namespace BloombergLP { namespace bslstl { #ifdef BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE template <std::size_t... INTS> using Pair_IndexSequence = bslmf::IntegerSequence<std::size_t, INTS...>; // 'Pair_IndexSequence' is an alias to the 'bslmf::IntegerSequence' class // template specialized for the common case of the integer sequence were // the element type 'T' is 'std::size_t'. template <std::size_t N> using Pair_MakeIndexSequence = bslmf::MakeIntegerSequence<std::size_t, N>; // 'Pair_MakeIndexSequence' is an alias template to the // 'bslmf::MakeIntegerSequence' meta-function specialized for the common // case of the integer sequence were the element type 'T' is 'std::size_t'. #endif } // close package namespace } // close enterprise namespace namespace bsl { // ========================= // trait Pair_AllocatorIdiom // ========================= typedef bsl::integral_constant<int, 0> Pair_BslmaIdiomNone; // Type tag for types that do not take a 'bslma::Allocator*' constructor // argument. typedef bsl::integral_constant<int, 1> Pair_BslmaIdiomAtEnd; // Type tag for types that take a 'bslma::Allocator*' as the last argument // of their constructors. typedef bsl::integral_constant<int, 2> Pair_BslmaIdiomAllocatorArgT; // Type tag for types that take a 'bslma::Allocator*' as the second // argument of their constructors, following an argument of type // 'bsl::allocator_arg_t'. template <class TYPE> struct Pair_BslmaIdiom : bsl::integral_constant<int, BloombergLP::bslma::UsesBslmaAllocator<TYPE>::value ? (BloombergLP::bslmf::UsesAllocatorArgT<TYPE>::value ? Pair_BslmaIdiomAllocatorArgT::value : Pair_BslmaIdiomAtEnd::value) : Pair_BslmaIdiomNone::value> { // This component-private meta-function determines whether the specified // 'TYPE' template parameter takes a 'bslma::Allocator*' constructor // argument and, if so, whether that argument is at the end of the argument // list or at the beginning of the argument list following an argument of // type 'bsl::allocator_arg_t'. This type derived from // 'bsl::integral_constant<int, N>' where 'N' is the number of additional // parameters required to pass an allocator to a constructor using the // chosen idiom. }; #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) template <class TYPE, class ... ARGS> struct Pair_ConstructionParametersPackLength : integral_constant<int, sizeof...(ARGS) + Pair_BslmaIdiom<TYPE>::value > { // This component-private component-private meta-function determines the // number of elements in a tuple containing parameters for piecewise // construction of a 'bsl::pair' member having the specified 'TYPE'. // Result value depends on the 'TYPE', whether it takes a // 'bslma::Allocator*' constructor argument and, if so, whether that // argument follows an argument of type 'bsl::allocator_arg_t'. }; #endif // =================== // struct Pair_ImpUtil // =================== struct Pair_ImpUtil { // This 'struct' provides a namespace for utility functions used to // creating a tuple, containing arguments for the constructor of pair // element in the process of 'bsl::pair' piecewise construction. // CLASS METHODS #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) template <class ... ARGS> static std::tuple<ARGS...> concatAllocator( BSLS_COMPILERFEATURES_FORWARD_REF(std::tuple<ARGS...>) tpl, BloombergLP::bslma::Allocator *alloc, bsl::Pair_BslmaIdiomNone); // Construct and return by value a tuple, containing arguments for the // corresponding constructor of (template parameter) 'TYPE', // forwarding in order the elements in the specified 'tpl' and // discarding the specified 'alloc', because 'TYPE' does not support // 'bslma'-style allocators. This method provides the no-throw // exception-safety guarantee. template <class ... ARGS> static std::tuple<ARGS..., BloombergLP::bslma::Allocator *> concatAllocator( BSLS_COMPILERFEATURES_FORWARD_REF(std::tuple<ARGS...>) tpl, BloombergLP::bslma::Allocator *alloc, bsl::Pair_BslmaIdiomAtEnd); // Construct and return by value a tuple, containing arguments for the // corresponding constructor of (template parameter) 'TYPE', // forwarding in order the elements in the specified 'tpl' and // appending the specified 'alloc', because 'TYPE' takes a // 'bslma'-style allocator as the last constructor argument. This // method provides the no-throw exception-safety guarantee. template <class ... ARGS> static std::tuple<bsl::allocator_arg_t, BloombergLP::bslma::Allocator *, ARGS...> concatAllocator( BSLS_COMPILERFEATURES_FORWARD_REF(std::tuple<ARGS...>) tpl, BloombergLP::bslma::Allocator *alloc, bsl::Pair_BslmaIdiomAllocatorArgT); // Construct and return by value a tuple, containing arguments for the // corresponding constructor of (template parameter) 'TYPE', forwarding // in order the elements in the specified 'tpl' preceded by // 'bsl::allocator_arg' object and the specified 'alloc', because // 'TYPE' takes a 'bslma'-style allocator as the second constructor // argument preceded by 'bsl::allocator_arg'. This method provides the // no-throw exception-safety guarantee. #endif #if defined(BSLS_COMPILERFEATURES_SUPPORT_NOEXCEPT) && \ defined(BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE) template <class TYPE1, class TYPE2> static constexpr bool hasNothrowSwap() // Utility function to determine whether 'swap()' is 'noexcept (true)' // when called with the specified (template) arguments 'TYPE1' and // 'TYPE2'. This function is only defined on platforms where // 'noexcept' is supported but the newer, C++17 compatible trait // 'bsl::is_nothrow_swappable' is not available. { using std::swap; typedef BloombergLP::bslmf::Util U; return BSLS_KEYWORD_NOEXCEPT_OPERATOR(swap(U::declval<TYPE1&>(), U::declval<TYPE1&>())) && BSLS_KEYWORD_NOEXCEPT_OPERATOR(swap(U::declval<TYPE2&>(), U::declval<TYPE2&>())); } #endif }; // ================= // struct Pair_First // ================= template <class TYPE> struct Pair_First { // This component-private 'class' holds the 'first' data member of a 'pair' // and constructs it appropriately. private: // PRIVATE TYPES typedef BloombergLP::bslmf::MovableRefUtil MovUtil; // This typedef is a convenient alias for the utility associated with // implementing movable references in C++03 and C++11 environments. typedef typename Pair_BslmaIdiom<TYPE>::type FirstBslmaIdiom; protected: public: // PUBLIC DATA TYPE first; // CREATORS #if !defined(BSLSTL_PAIR_DO_NOT_DEFAULT_THE_DEFAULT_CONSTRUCTOR) template < class BSLSTL_DUMMY = TYPE, typename std::enable_if<std::is_default_constructible<BSLSTL_DUMMY>::value, int>::type = 0> BSLS_KEYWORD_CONSTEXPR Pair_First() : first() { // This constructor template must be defined inline inside the // class definition, as Microsoft Visual C++ does not recognize the // definition as matching this signature when placed out-of-line. } #else BSLS_KEYWORD_CONSTEXPR Pair_First(); #endif // Construct the 'first' member of a 'pair' using the default // constructor for (template parameter) 'TYPE'. Pair_First(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); Pair_First(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd); Pair_First(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT); // Construct the 'first' member of a 'pair', using the specified // 'basicAllocator' to supply memory. Note that exactly one of these // three constructors is enabled at compile-time for (template // parameter) type 'TYPE' based on the following respective criteria: // 1) 'TYPE' does not support 'bslma'-style allocators, 2) 'TYPE' // takes a 'bslma'-style allocator as the last constructor argument, // and 3) 'TYPE' takes a 'bslma'-style allocator as the second // constructor argument preceded by 'bsl::allocator_arg'. BSLS_KEYWORD_CONSTEXPR explicit Pair_First( typename bsl::add_lvalue_reference<const TYPE>::type value); // Construct the 'first' member from the specified non-modifiable // 'value', without specifying an allocator. #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class PARAM> BSLS_KEYWORD_CONSTEXPR explicit Pair_First(PARAM&& value); #else template <class PARAM> BSLS_KEYWORD_CONSTEXPR explicit Pair_First(const PARAM& value); template <class PARAM> BSLS_KEYWORD_CONSTEXPR explicit Pair_First(PARAM& value); #endif // TBD: improve comment. // Construct the 'first' member from the specified 'value', without // specifying an allocator. This function (perfectly) forwards 'value' // to the constructor of (template parameter) 'TYPE'. #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class PARAM> Pair_First(PARAM&& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); template <class PARAM> Pair_First(PARAM&& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd); template <class PARAM> Pair_First(PARAM&& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT); #else template <class PARAM> Pair_First(const PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); template <class PARAM> Pair_First(PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); template <class PARAM> Pair_First(const PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd); template <class PARAM> Pair_First(PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd); template <class PARAM> Pair_First(const PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT); template <class PARAM> Pair_First(PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT); #endif // Construct the 'first' member of a 'pair' from the specified 'value', // using the specified 'basicAllocator' to supply memory. This // function (perfectly) forwards 'value' to the constructor of // (template parameter) 'TYPE'. Note that exactly one of these three // constructors is enabled at compile-time for (template parameter) // type 'TYPE' based on the following respective criteria: 1) 'TYPE' // does not support 'bslma'-style allocators, 2) 'TYPE' takes a // 'bslma'-style allocator as the last constructor argument, and 3) // 'TYPE' takes a 'bslma'-style allocator as the second constructor // argument preceded by 'bsl::allocator_arg'. #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \ && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE) template <class ...ARGS, size_t ...I> Pair_First(std::tuple<ARGS...>&& argsPack, BloombergLP::bslstl::Pair_IndexSequence<I...>); // Construct the 'first' member of a 'pair', forwarding in order the // elements in the specified 'argsPack' to the corresponding // constructor of (template parameter) 'TYPE'. The length of the // 'argsPack' is equal to the lenght of the specified (template // parameter pack) 'I...' and passed to the constructor via the // 'Pair_IndexSequence' object. #endif //! Pair_First(const Pair_First&) = default; //! Pair_First(Pair_First&&) = default; //! Pair_First& operator=(Pair_First&&) = default; //! ~Pair_First() = default; }; template <class TYPE> struct Pair_First<TYPE&> { // This component-private 'class' holds the 'first' data member of a 'pair' // and constructs it appropriately. protected: // PROTECTED DATA TYPE& first; // CREATORS BSLS_KEYWORD_CONSTEXPR explicit Pair_First(TYPE& value); // Bind the specified 'value' into the 'first' reference-member. #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class PARAM> BSLS_KEYWORD_CONSTEXPR explicit Pair_First(PARAM&& value); #else template <class PARAM> BSLS_KEYWORD_CONSTEXPR explicit Pair_First(const PARAM& value); // for derived-to-const-base-ref template <class PARAM> BSLS_KEYWORD_CONSTEXPR explicit Pair_First(PARAM& value); #endif // Bind the specified 'value' into the 'first' reference-member. // TBD: Consider SFINAE-ing these constructors #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class PARAM> BSLS_KEYWORD_CONSTEXPR Pair_First(PARAM&& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); #else template <class PARAM> BSLS_KEYWORD_CONSTEXPR Pair_First(const PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); template <class PARAM> BSLS_KEYWORD_CONSTEXPR Pair_First(PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); #endif // Bind the specified 'value' into the 'first' reference-member. The // specified 'basicAllocator' is not used. #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \ && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE) template <class ARG> BSLS_KEYWORD_CONSTEXPR Pair_First(std::tuple<ARG>&& arg, BloombergLP::bslstl::Pair_IndexSequence<0u>); // Construct the 'first' member of a 'pair', forwarding in order the // elements in the specified 'argsPack' to the corresponding // constructor of (template parameter) 'TYPE'. The length of the // 'argsPack' is equal to the lenght of the specified (template // parameter pack) 'I...' and passed to the constructor via the // 'Pair_IndexSequence' object. #endif //! ~Pair_First() = default; // MANIPULATORS #if !defined(BSLSTL_PAIR_NO_IMPLICIT_DELETED_FOR_MOVE_OPS) Pair_First(const Pair_First&) = default; Pair_First(Pair_First&&) = default; #endif Pair_First& operator=(const Pair_First& rhs) BSLS_KEYWORD_NOEXCEPT; }; #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class TYPE> struct Pair_First<TYPE&&> { // This component-private 'class' holds the 'first' data member of a 'pair' // and constructs it appropriately. protected: // PROTECTED DATA TYPE&& first; // CREATORS BSLS_KEYWORD_CONSTEXPR explicit Pair_First(TYPE&& value); // Construct the 'first' member from the specified non-modifiable // 'value', without specifying an allocator. template <class PARAM> BSLS_KEYWORD_CONSTEXPR explicit Pair_First(PARAM&& value); // TBD: improve comment. // Construct the 'first' member from the specified 'value', without // specifying an allocator. This function (perfectly) forwards 'value' // to the constructor of (template parameter) 'TYPE'. // TBD: Consider SFINAE-ing this constructor, but maybe better handled // at the 'pair' level? template <class PARAM> BSLS_KEYWORD_CONSTEXPR Pair_First(PARAM&& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); // Construct the 'first' member of a 'pair' from the specified 'value', // using the specified 'basicAllocator' to supply memory. This // function (perfectly) forwards 'value' to the constructor of // (template parameter) 'TYPE'. Note that exactly one of these three // constructors is enabled at compile-time for (template parameter) // type 'TYPE' based on the following respective criteria: 1) 'TYPE' // does not support 'bslma'-style allocators, 2) 'TYPE' takes a // 'bslma'-style allocator as the last constructor argument, and 3) // 'TYPE' takes a 'bslma'-style allocator as the second constructor // argument preceded by 'bsl::allocator_arg'. #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \ && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE) template <class ARG> BSLS_KEYWORD_CONSTEXPR Pair_First(std::tuple<ARG>&& arg, BloombergLP::bslstl::Pair_IndexSequence<0u>); // Construct the 'first' member of a 'pair', forwarding in order the // elements in the specified 'argsPack' to the corresponding // constructor of (template parameter) 'TYPE'. The length of the // 'argsPack' is equal to the lenght of the specified (template // parameter pack) 'I...' and passed to the constructor via the // 'Pair_IndexSequence' object. #endif //! ~Pair_First() = default; // MANIPULATORS #if !defined(BSLSTL_PAIR_NO_IMPLICIT_DELETED_FOR_MOVE_OPS) Pair_First(const Pair_First&) = default; Pair_First(Pair_First&&) = default; #endif Pair_First& operator=(const Pair_First& rhs) BSLS_KEYWORD_NOEXCEPT; }; #endif // ================== // struct Pair_Second // ================== template <class TYPE> struct Pair_Second { // This component-private 'class' holds the 'second' data member of a // 'pair' and constructs it appropriately. private: // PRIVATE TYPES typedef BloombergLP::bslmf::MovableRefUtil MovUtil; // This typedef is a convenient alias for the utility associated with // implementing movable references in C++03 and C++11 environments. typedef typename Pair_BslmaIdiom<TYPE>::type SecondBslmaIdiom; protected: // PROTECTED DATA TYPE second; // CREATORS #if !defined(BSLSTL_PAIR_DO_NOT_DEFAULT_THE_DEFAULT_CONSTRUCTOR) template < class BSLSTL_DUMMY = TYPE, typename std::enable_if<std::is_default_constructible<BSLSTL_DUMMY>::value, int>::type = 0> BSLS_KEYWORD_CONSTEXPR Pair_Second() : second() { // This constructor template must be defined inline inside the // class definition, as Microsoft Visual C++ does not recognize the // definition as matching this signature when placed out-of-line. } #else BSLS_KEYWORD_CONSTEXPR Pair_Second(); #endif // Construct the 'second' member of a 'pair' using the default // constructor for (template parameter) type 'TYPE'. Pair_Second(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); Pair_Second(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd); Pair_Second(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT); // Construct the 'second' member of a 'pair', using the specified // 'basicAllocator' to supply memory. Note that exactly one of these // three constructors is enabled at compile-time for (template // parameter) type 'TYPE' based on the following respective criteria: // 1) 'TYPE' does not support 'bslma'-style allocators, 2) 'TYPE' // takes a 'bslma'-style allocator as the last constructor argument, // and 3) 'TYPE' takes a 'bslma'-style allocator as the second // constructor argument preceded by 'bsl::allocator_arg'. BSLS_KEYWORD_CONSTEXPR explicit Pair_Second( typename bsl::add_lvalue_reference<const TYPE>::type value); // Construct the 'second' member from the specified non-modifiable // 'value', without specifying an allocator. #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class PARAM> BSLS_KEYWORD_CONSTEXPR explicit Pair_Second(PARAM&& value); #else template <class PARAM> BSLS_KEYWORD_CONSTEXPR explicit Pair_Second(const PARAM& value); template <class PARAM> BSLS_KEYWORD_CONSTEXPR explicit Pair_Second(PARAM& value); #endif // Construct the 'second' member from the specified 'value', without // specifying an allocator. This function (perfectly) forwards 'value' // to the constructor of (template parameter) 'TYPE'. #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class PARAM> Pair_Second(PARAM&& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); template <class PARAM> Pair_Second(PARAM&& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd); template <class PARAM> Pair_Second(PARAM&& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT); #else template <class PARAM> Pair_Second(const PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); template <class PARAM> Pair_Second(PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); template <class PARAM> Pair_Second(const PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd); template <class PARAM> Pair_Second(PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd); template <class PARAM> Pair_Second(const PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT); template <class PARAM> Pair_Second(PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT); #endif // Construct the 'second' member of a 'pair' from the specified // forwarding reference 'value', using the specified 'basicAllocator' // to supply memory. This function (perfectly) forwards 'value' to the // constructor of (template parameter) 'TYPE'. Note that exactly one // of these three constructors is enabled at compile-time for (template // parameter) type 'TYPE' based on the following respective criteria: // 1) 'TYPE' does not support 'bslma'-style allocators, 2) 'TYPE' takes // a 'bslma'-style allocator as the last constructor argument, and 3) // 'TYPE' takes a 'bslma'-style allocator as the second constructor // argument preceded by 'bsl::allocator_arg'. #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \ && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE) template <class ...ARGS, size_t ...I> Pair_Second(std::tuple<ARGS...>&& argsPack, BloombergLP::bslstl::Pair_IndexSequence<I...>); // Construct the 'second' member of a 'pair', forwarding in order the // elements in the specified 'argsPack' to the corresponding // constructor of (template parameter) 'TYPE'. The length of the // 'argsPack' is equal to the lenght of the specified (template // parameter pack) 'I...' and passed to the constructor via the // 'Pair_IndexSequence' object. #endif //! Pair_Second(const Pair_Second&) = default; //! Pair_Second(Pair_Second&&) = default; //! Pair_Second& operator=(Pair_Second&&) = default; //! ~Pair_Second() = default; }; template <class TYPE> struct Pair_Second<TYPE&> { // This component-private 'class' holds the 'second' data member of a // 'pair' and constructs it appropriately. protected: // PUBLIC DATA TYPE& second; // CREATORS BSLS_KEYWORD_CONSTEXPR explicit Pair_Second(TYPE& value); // Construct the 'second' member from the specified non-modifiable // 'value', without specifying an allocator. #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class PARAM> BSLS_KEYWORD_CONSTEXPR explicit Pair_Second(PARAM&& value); #else template <class PARAM> BSLS_KEYWORD_CONSTEXPR explicit Pair_Second(const PARAM& value); template <class PARAM> BSLS_KEYWORD_CONSTEXPR explicit Pair_Second(PARAM& value); #endif // Construct the 'second' member from the specified 'value', without // specifying an allocator. This function (perfectly) forwards 'value' // to the constructor of (template parameter) 'TYPE'. #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class PARAM> BSLS_KEYWORD_CONSTEXPR Pair_Second(PARAM&& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); #else template <class PARAM> BSLS_KEYWORD_CONSTEXPR Pair_Second(const PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); template <class PARAM> BSLS_KEYWORD_CONSTEXPR Pair_Second(PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); #endif // Construct the 'second' member of a 'pair' from the specified // forwarding reference 'value', using the specified 'basicAllocator' // to supply memory. This function (perfectly) forwards 'value' to the // constructor of (template parameter) 'TYPE'. Note that exactly one // of these three constructors is enabled at compile-time for (template // parameter) type 'TYPE' based on the following respective criteria: // 1) 'TYPE' does not support 'bslma'-style allocators, 2) 'TYPE' takes // a 'bslma'-style allocator as the last constructor argument, and 3) // 'TYPE' takes a 'bslma'-style allocator as the second constructor // argument preceded by 'bsl::allocator_arg'. #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \ && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE) template <class ARG> BSLS_KEYWORD_CONSTEXPR Pair_Second(std::tuple<ARG>&& arg, BloombergLP::bslstl::Pair_IndexSequence<0u>); // Construct the 'second' member of a 'pair', forwarding in order the // elements in the specified 'argsPack' to the corresponding // constructor of (template parameter) 'TYPE'. The length of the // 'argsPack' is equal to the lenght of the specified (template // parameter pack) 'I...' and passed to the constructor via the // 'Pair_IndexSequence' object. #endif //! ~Pair_Second() = default; // MANIPULATORS #if !defined(BSLSTL_PAIR_NO_IMPLICIT_DELETED_FOR_MOVE_OPS) Pair_Second(const Pair_Second&) = default; Pair_Second(Pair_Second&&) = default; #endif Pair_Second& operator=(const Pair_Second& rhs) BSLS_KEYWORD_NOEXCEPT; }; #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class TYPE> struct Pair_Second<TYPE&&> { // This component-private 'class' holds the 'second' data member of a // 'pair' and constructs it appropriately. protected: // PROTECTED DATA TYPE&& second; // CREATORS BSLS_KEYWORD_CONSTEXPR explicit Pair_Second(TYPE&& value); // Construct the 'second' member from the specified non-modifiable // 'value', without specifying an allocator. template <class PARAM> BSLS_KEYWORD_CONSTEXPR explicit Pair_Second(PARAM&& value); // Construct the 'second' member from the specified 'value', without // specifying an allocator. This function (perfectly) forwards 'value' // to the constructor of (template parameter) 'TYPE'. template <class PARAM> BSLS_KEYWORD_CONSTEXPR Pair_Second(PARAM&& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomNone); // Construct the 'second' member of a 'pair' from the specified // forwarding reference 'value', using the specified 'basicAllocator' // to supply memory. This function (perfectly) forwards 'value' to the // constructor of (template parameter) 'TYPE'. Note that exactly one // of these three constructors is enabled at compile-time for (template // parameter) type 'TYPE' based on the following respective criteria: // 1) 'TYPE' does not support 'bslma'-style allocators, 2) 'TYPE' takes // a 'bslma'-style allocator as the last constructor argument, and 3) // 'TYPE' takes a 'bslma'-style allocator as the second constructor // argument preceded by 'bsl::allocator_arg'. #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \ && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE) template <class ARG> BSLS_KEYWORD_CONSTEXPR Pair_Second(std::tuple<ARG>&& arg, BloombergLP::bslstl::Pair_IndexSequence<0u>); // Construct the 'second' member of a 'pair', forwarding in order the // elements in the specified 'argsPack' to the corresponding // constructor of (template parameter) 'TYPE'. The length of the // 'argsPack' is equal to the lenght of the specified (template // parameter pack) 'I...' and passed to the constructor via the // 'Pair_IndexSequence' object. #endif //! ~Pair_Second() = default; // MANIPULATORS #if !defined(BSLSTL_PAIR_NO_IMPLICIT_DELETED_FOR_MOVE_OPS) Pair_Second(const Pair_Second&) = default; Pair_Second(Pair_Second&&) = default; #endif Pair_Second& operator=(const Pair_Second& rhs) BSLS_KEYWORD_NOEXCEPT; }; #endif // ========== // class pair // ========== template <class T1, class T2> class pair : public Pair_First<T1>, public Pair_Second<T2> { // The class template 'pair' provides a pair of public data members, // 'first' and 'second', of type 'T1' and 'T2' respectively. If either // 'T1' or 'T2' uses 'bslma::Allocator' for memory management, then provide // an optional 'bslma::Allocator' argument for each constructor, to be // passed through to the constructors of 'first' and/or 'second' as // appropriate. The interface to this class is identical to the standard // 'std::pair' except for the addition of the allocators. Note that the // implementation of this class provides 'first' and 'second' through // multiple base classes in order to simplify construction of each member // when allowing for the various rules for passing allocators in C++11. // PRIVATE TYPES typedef Pair_First<T1> FirstBase; typedef Pair_Second<T2> SecondBase; // 'ThirdBase' and 'HomePlate' left as an exercise for the reader. typedef typename Pair_BslmaIdiom<T1>::type FirstBslmaIdiom; typedef typename Pair_BslmaIdiom<T2>::type SecondBslmaIdiom; typedef BloombergLP::bslmf::MovableRefUtil MovUtil; // This typedef is a convenient alias for the utility associated with // movable references. public: // PUBLIC TYPES typedef T1 first_type; typedef T2 second_type; // PUBLIC DATA using FirstBase::first; using SecondBase::second; // CREATORS #if !defined(BSLSTL_PAIR_DO_NOT_DEFAULT_THE_DEFAULT_CONSTRUCTOR) BSLS_KEYWORD_CONSTEXPR pair() = default; #else BSLS_KEYWORD_CONSTEXPR pair(); #endif explicit pair(BloombergLP::bslma::Allocator *basicAllocator); // Construct a 'pair' with the 'first' and 'second' members initialized // to default values. Optionally specify a 'basicAllocator', used to // supply memory for each of 'first' and 'second' when its type // (template parameter 'T1' or 'T2', respectively) uses 'bslma'-style // allocators. This method requires that 'T1' and 'T2' be // default-constructible. pair(const pair& original, BloombergLP::bslma::Allocator *basicAllocator); // Construct a 'pair' having the same value as that of the specified // 'original' pair. Optionally specify a 'basicAllocator', used to // supply memory for each of 'first' and 'second' when its type // (template parameter 'T1' or 'T2', respectively) uses 'bslma'-style // allocators. Note that the copy constructor is implicitly declared // (if 'T1' and 'T2' are both 'copy-constructible') by compilers that // do not support defaulted declarations. #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) //! pair(pair&& original); // Allow move ctor to implicitly default/delete pair(pair&& original, BloombergLP::bslma::Allocator *basicAllocator); #else BSLS_KEYWORD_CONSTEXPR pair(BloombergLP::bslmf::MovableRef<pair> original); pair(BloombergLP::bslmf::MovableRef<pair> original, BloombergLP::bslma::Allocator *basicAllocator); // Construct a pair having the same value as that of the specified // 'original' before the call to the move constructor. Optionally // specify a 'basicAllocator', used to supply memory for each of // 'first' and 'second' when its type (template parameter 'T1' or 'T2', // respectively) uses 'bslma'-style allocators. Note that 'original' // is left in a valid but unspecified state. Also note that this // method requires that 'T1' and 'T2' be move-constructible. Note that // the move constructor is implicitly declared (if 'T1' and 'T2' are // both move-constructible) by compilers that do not support defaulted // declarations, but do support rvalue references. #endif BSLS_KEYWORD_CONSTEXPR pair(typename bsl::add_lvalue_reference<const T1>::type a, typename bsl::add_lvalue_reference<const T2>::type b); pair(typename bsl::add_lvalue_reference<const T1>::type a, typename bsl::add_lvalue_reference<const T2>::type b, BloombergLP::bslma::Allocator *basicAllocator); // Construct a 'pair' with the 'first' member initialized to the // specified 'a' value and the 'second' member initialized to the // specified 'b' value. Optionally specify a 'basicAllocator', used to // supply memory for each of 'first' and 'second' when its type // (template parameter 'T1' or 'T2', respectively) uses 'bslma'-style // allocators. This method requires that 'T1' and 'T2' be // 'copy-constructible'. #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair(PARAM_1&& a, PARAM_2&& b, typename bsl::enable_if<std::is_constructible<T1, PARAM_1>::value && std::is_constructible<T2, PARAM_2>::value && !(bsl::is_pointer<typename bsl::remove_reference<PARAM_2>::type>::value && bsl::is_convertible<PARAM_2, BloombergLP::bslma::Allocator *>::value), void *>::type = 0) : FirstBase(std::forward<PARAM_1>(a)) , SecondBase(std::forward<PARAM_2>(b)) { // The implementation is placed here in the class definition to work // around a Microsoft C++ compiler (MSVC 2010) bug where the definition // cannot be matched to the declaration when an 'enable_if' is used. } template <class PARAM_1, class PARAM_2> pair(PARAM_1&& a, PARAM_2&& b, BloombergLP::bslma::Allocator *basicAllocator); #else template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair(const PARAM_1& a, const PARAM_2& b, typename bsl::enable_if<bsl::is_convertible<PARAM_1, T1>::value && bsl::is_convertible<PARAM_2, T2>::value && !(bsl::is_pointer<typename bsl::remove_reference<PARAM_2>::type>::value && bsl::is_convertible<PARAM_2, BloombergLP::bslma::Allocator *>::value), void *>::type = 0) : FirstBase(a) , SecondBase(b) { // The implementation is placed here in the class definition to work // around a Microsoft C++ compiler (MSVC 2010) bug where the definition // cannot be matched to the declaration when an 'enable_if' is used. } template <class PARAM_1, class PARAM_2> pair(const PARAM_1& a, const PARAM_2& b, BloombergLP::bslma::Allocator *basicAllocator); template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair(PARAM_1& a, const PARAM_2& b, typename bsl::enable_if<bsl::is_convertible<PARAM_1, T1>::value && bsl::is_convertible<PARAM_2, T2>::value && !(bsl::is_pointer<typename bsl::remove_reference<PARAM_2>::type>::value && bsl::is_convertible<PARAM_2, BloombergLP::bslma::Allocator *>::value), void *>::type = 0) : FirstBase(a) , SecondBase(b) { // The implementation is placed here in the class definition to work // around a Microsoft C++ compiler (MSVC 2010) bug where the definition // cannot be matched to the declaration when an 'enable_if' is used. } template <class PARAM_1, class PARAM_2> pair(PARAM_1& a, const PARAM_2& b, BloombergLP::bslma::Allocator *basicAllocator); template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair(const PARAM_1& a, PARAM_2& b, typename bsl::enable_if<bsl::is_convertible<PARAM_1, T1>::value && bsl::is_convertible<PARAM_2, T2>::value && !(bsl::is_pointer<typename bsl::remove_reference<PARAM_2>::type>::value && bsl::is_convertible<PARAM_2, BloombergLP::bslma::Allocator *>::value), void *>::type = 0) : FirstBase(a) , SecondBase(b) { // The implementation is placed here in the class definition to work // around a Microsoft C++ compiler (MSVC 2010) bug where the definition // cannot be matched to the declaration when an 'enable_if' is used. } template <class PARAM_1, class PARAM_2> pair(const PARAM_1& a, PARAM_2& b, BloombergLP::bslma::Allocator *basicAllocator); template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair(PARAM_1& a, PARAM_2& b, typename bsl::enable_if<bsl::is_convertible<PARAM_1, T1>::value && bsl::is_convertible<PARAM_2, T2>::value && !(bsl::is_pointer<typename bsl::remove_reference<PARAM_2>::type>::value && bsl::is_convertible<PARAM_2, BloombergLP::bslma::Allocator *>::value), void *>::type = 0) : FirstBase(a) , SecondBase(b) { // The implementation is placed here in the class definition to work // around a Microsoft C++ compiler (MSVC 2010) bug where the definition // cannot be matched to the declaration when an 'enable_if' is used. } template <class PARAM_1, class PARAM_2> pair(PARAM_1& a, PARAM_2& b, BloombergLP::bslma::Allocator *basicAllocator); #endif // Construct a pair with the 'first' member initialized to the specified // 'a' value of (template parameter) type 'PARAM_1' and the 'second' member // initialized to the specified 'b' value of (template parameter) type // 'PARAM_2'. Optionally specify a 'basicAllocator', used to supply memory // for each of 'first' and 'second' when its type (template parameter 'T1' // or 'T2', respectively) uses 'bslma'-style allocators. This method // requires that 'T1' and 'T2' be convertible from 'PARAM_1' and 'PARAM_2', // respectively. #if defined(BSLSTL_PAIR_ENABLE_ALL_CONVERTIBILITY_CHECKS) template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair(const pair<PARAM_1, PARAM_2>& other, typename bsl::enable_if<bsl::is_convertible<PARAM_1, T1>::value && bsl::is_convertible<PARAM_2, T2>::value, void *>::type = 0); template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair(const 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, void *>::type = 0); #else template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair(const pair<PARAM_1, PARAM_2>& other); template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair(const std::pair<PARAM_1, PARAM_2>& other); #endif template <class PARAM_1, class PARAM_2> pair(const pair<PARAM_1, PARAM_2>& other, BloombergLP::bslma::Allocator *basicAllocator); template <class PARAM_1, class PARAM_2> pair(const std::pair<PARAM_1, PARAM_2>& other, BloombergLP::bslma::Allocator *basicAllocator); // Construct a 'pair' from the specified 'other' pair, holding 'first' // and 'second' values of (template parameter) type 'PARAM_1' and // 'PARAM_2' respectively. Optionally specify a 'basicAllocator', used // to supply memory for each of 'first' and 'second' when its type // (template parameter 'T1' or 'T2', respectively) uses 'bslma'-style // allocators. This method requires that 'T1' and 'T2' be convertible // from 'PARAM_1' and 'PARAM_2', respectively. #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair(pair<PARAM_1, PARAM_2>&& other, typename bsl::enable_if<bsl::is_convertible<PARAM_1, T1>::value && bsl::is_convertible<PARAM_2, T2>::value, void *>::type = 0); template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair(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, void *>::type = 0); template <class PARAM_1, class PARAM_2> pair(pair<PARAM_1, PARAM_2>&& other, BloombergLP::bslma::Allocator *basicAllocator); template <class PARAM_1, class PARAM_2> pair(std::pair<PARAM_1, PARAM_2>&& other, BloombergLP::bslma::Allocator *basicAllocator); // Construct a 'pair' from the specified 'other' pair, holding 'first' // and 'second' values of (template parameter) type 'PARAM_1' and // 'PARAM_2' respectively. Optionally specify a 'basicAllocator', used // to supply memory for each of 'first' and 'second' when its type // (template parameter 'T1' or 'T2', respectively) uses 'bslma'-style // allocators. This method requires that 'T1' and 'T2' be convertible // from 'PARAM_1' and 'PARAM_2', respectively. #else template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair(BloombergLP::bslmf::MovableRef<pair<PARAM_1, PARAM_2> > other, typename bsl::enable_if<bsl::is_convertible<PARAM_1, T1>::value && bsl::is_convertible<PARAM_2, T2>::value, void *>::type = 0) : FirstBase(MovUtil::move(MovUtil::access(other).first)) , SecondBase(MovUtil::move(MovUtil::access(other).second)) { // The implementation is placed here in the class definition to work // around a Microsoft C++ compiler (version 16) bug where the // definition cannot be matched to the declaration when an 'enable_if' // is used. } template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair( BloombergLP::bslmf::MovableRef<std::pair<PARAM_1, PARAM_2> > other, typename bsl::enable_if<bsl::is_convertible<PARAM_1, T1>::value && bsl::is_convertible<PARAM_2, T2>::value, void *>::type = 0) : FirstBase(MovUtil::move(MovUtil::access(other).first)) , SecondBase(MovUtil::move(MovUtil::access(other).second)) { // The implementation is placed here in the class definition to work // around a Microsoft C++ compiler (version 16) bug where the // definition cannot be matched to the declaration when an 'enable_if' // is used. } template <class PARAM_1, class PARAM_2> pair( BloombergLP::bslmf::MovableRef<pair<PARAM_1, PARAM_2> > other, BloombergLP::bslma::Allocator *basicAllocator); template <class PARAM_1, class PARAM_2> pair(BloombergLP::bslmf::MovableRef<std::pair<PARAM_1, PARAM_2> > other, BloombergLP::bslma::Allocator *basicAllocator); // Construct a 'pair' from the specified 'other' pair, holding 'first' // and 'second' values of (template parameter) type 'PARAM_1' and // 'PARAM_2' respectively. Optionally specify a 'basicAllocator', used // to supply memory for each of 'first' and 'second' when its type // (template parameter 'T1' or 'T2', respectively) uses 'bslma'-style // allocators. This method requires that 'T1' and 'T2' be convertible // from 'PARAM_1' and 'PARAM_2', respectively. #endif #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR) template<class ...ARGS_1, class ...ARGS_2> pair(std::piecewise_construct_t, std::tuple<ARGS_1...> first_args, std::tuple<ARGS_2...> second_args); template<class ...ARGS_1, class ...ARGS_2> pair(std::piecewise_construct_t, std::tuple<ARGS_1...> first_args, std::tuple<ARGS_2...> second_args, BloombergLP::bslma::Allocator *basicAllocator); // Create a 'pair' from piece-wise construction of 'first' and 'second' // values by forwarding in order the elements in the specified // 'first_args' and 'second_args' tuples to the corresponding // constructor of (template parameter) types 'T1' and 'T2', // respectively. Optionally specify a 'basicAllocator', used to supply // memory for each of 'first' and 'second' when its type (template // parameter 'T1' or 'T2', respectively) uses 'bslma'-style allocators. // Allocators can also be passed as tuple members straight to 'T1' or // 'T2' (or both) constructors using the first version (but use of the // second version for this approach will result in a compile-time // error). This method requires that 'T1' and 'T2' be constructible // from (the variable number of template parameters) 'ARGS_1' and // 'ARGS_2' respectively. #endif #ifndef BDE_OMIT_INTERNAL_DEPRECATED template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair(const BloombergLP::bslma::ManagedPtr_PairProxy<PARAM_1, PARAM_2>& rhs); // IMPLICIT // Create a 'pair' that has the same value as the specified 'rhs' pair // proxy. The behavior is undefined unless 'T1' is constructible from // 'PARAM_1' and 'T2' is constructible from from 'PARAM_2'. #endif // BDE_OMIT_INTERNAL_DEPRECATED //! ~pair() = default; // Destroy this object. Call destructors on 'first' and 'second'. // MANIPULATORS template <class PARAM_1, class PARAM_2> pair& operator=(const pair<PARAM_1, PARAM_2>& rhs); // Assign to this 'pair' from the specified 'rhs' pair, holding the // parameterized types 'PARAM_1' and 'PARAM_2', and return a reference // offering modifiable access to this object. Assign 'first' the value // in 'rhs.first' and 'second' the value in 'rhs.second'. Attempted // use of this assignment operator will not compile unless both 'T1' // and 'T2' supply assignment operators, and 'T1' is assignable from // 'PARAM_1' and 'T2' is assignable from 'PARAM_2'. #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class PARAM_1, class PARAM_2> pair& operator=(pair<PARAM_1, PARAM_2>&& rhs); // Assign to this 'pair' the value of the specified 'rhs' pair, holding // 'first' and 'second' values of (template parameter) type 'PARAM_1' // and 'PARAM_2' respectively, and return a reference providing // modifiable access to this object. This method requires that 'T1' be // assignable from 'PARAM_1' and 'T2' be assignable from 'PARAM_2'. #else pair& operator=(BloombergLP::bslmf::MovableRef<pair> rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(false); // Assign to this 'pair' the value of the specified 'rhs' pair (before // the call to the assignment), and return a reference providing // modifiable access to this object. Note that 'rhs' is left in a // valid but unspecified state. This method requires that (template // parameter) types 'T1' and 'T2' be move-assignable. template <class PARAM_1, class PARAM_2> pair& operator=( BloombergLP::bslmf::MovableRef<pair<PARAM_1, PARAM_2> > rhs); // Assign to this 'pair' the value of the specified 'rhs' pair, holding // 'first' and 'second' values of (template parameter) types 'PARAM_1' // and 'PARAM_2' respectively, and return a reference providing // modifiable access to this object. This method requires that 'T1' be // assignable from 'PARAM_1' and 'T2' be assignable from 'PARAM_2'. #endif template <class PARAM_1, class PARAM_2> pair& operator=(const std::pair<PARAM_1, PARAM_2>& rhs); // Assign to this 'pair' from the specified 'rhs' pair, where the type // 'rhs' is the pair type native to the compiler's library, holding the // parameterized types 'PARAM_1' and 'PARAM_2', and return a reference // offering modifiable access to this object. Assign 'first' the value // in 'rhs.first' and 'second' the value in 'rhs.second'. Attempted // use of this assignment operator will not compile unless both 'T1' // and 'T2' supply assignment operators, and 'T1' is assignable from // 'PARAM_1' and 'T2' is assignable from 'PARAM_2'. #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) template <class PARAM_1, class PARAM_2, typename bsl::enable_if<bsl::is_convertible<T1, PARAM_1>::value && bsl::is_convertible<T2, PARAM_2>::value, bool>::type = 0> operator std::tuple<PARAM_1&, PARAM_2&>() BSLS_KEYWORD_NOEXCEPT; // Return an 'std::tuple' object, holding references that provide // modifiable access to the members of this object. template <class PARAM_1, typename bsl::enable_if<bsl::is_convertible<T1, PARAM_1>::value, bool>::type = 0> operator std::tuple<PARAM_1&, decltype(std::ignore)&>() BSLS_KEYWORD_NOEXCEPT; // This partial specialization of 'template <class PARAM_1, class PARAM_2> // operator std::tuple<PARAM_1&, PARAM_2&>()', for when the (template // parameter) 'PARAM_2' (second element's type) is the type of // 'std::ignore'. template <class PARAM_2, typename bsl::enable_if<bsl::is_convertible<T2, PARAM_2>::value, bool>::type = 0> operator std::tuple<decltype(std::ignore)&, PARAM_2&>() BSLS_KEYWORD_NOEXCEPT; // This partial specialization of 'template <class PARAM_1, class PARAM_2> // operator std::tuple<PARAM_1&, PARAM_2&>()', for when the (template // parameter) 'PARAM_1' (first element's type) is the type of // 'std::ignore'. operator std::tuple<decltype(std::ignore)&, decltype(std::ignore)&>() BSLS_KEYWORD_NOEXCEPT // This partial specialization of 'template <class PARAM_1, class PARAM_2> // operator std::tuple<PARAM_1&, PARAM_2&>()', for when the (template // parameters) 'PARAM_1' (first element's type) and 'PARAM_2' (second // element's type) are the type of 'std::ignore'. Note that this method is // defined within the class body intentionally to avoid build failure on // MSVC 2015. { return std::tuple<decltype(std::ignore)&, decltype(std::ignore)&>(std::ignore, std::ignore); } #endif #if defined(BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE) void swap(pair& other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION( Pair_ImpUtil::hasNothrowSwap<T1, T2>()); #else void swap(pair& other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(bsl::is_nothrow_swappable<T1>::value && bsl::is_nothrow_swappable<T2>::value); #endif // Swap the value of this pair with the value of the specified 'other' // pair by applying 'swap' to each of the 'first' and 'second' pair // fields. Note that this method is no-throw only if 'swap' on each // field is no-throw. }; #ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD // CLASS TEMPLATE DEDUCTION GUIDES // When we are deducing from a 'pair<T1, T2>' (std or bsl) and an // 'Allocator *', we want to deduce a 'bsl::pair<T1, T2>', not a // bsl::pair<pair<T1, T2>, Allocator *>. // // Note that order is important; if given an 'Allocator *' and a // 'pair<T1, T2>' we deduce 'bsl::pair<Allocator *, pair<T1, T2>>'. template <class T1, class T2> pair(T1, T2) -> pair<T1, T2>; // Deduce the specified types 'T1' and 'T2' from the corresponding types // supplied to the constructor of 'pair'. template < class T1, class T2, class ALLOC, class = typename bsl::enable_if_t< bsl::is_convertible_v<ALLOC *, BloombergLP::bslma::Allocator *>> > pair(T1, T2, ALLOC *) -> pair<T1, T2>; // Deduce the specified types 'T1' and 'T2' from the corresponding types // supplied to the constructor of 'pair'. This guide does not participate // in deduction unless the specified 'ALLOC' inherits from // 'bslma::Allocator'. template < class T1, class T2, class ALLOC, class = typename bsl::enable_if_t< bsl::is_convertible_v<ALLOC *, BloombergLP::bslma::Allocator *>> > pair(pair<T1, T2>, ALLOC *) -> pair<T1, T2>; // Deduce the specified types 'T1' and 'T2' from the corresponding template // parameters of the 'bsl::pair' supplied to the constructor of 'pair'. // This guide does not participate in deduction unless the specified // 'ALLOC' inherits from 'bslma::Allocator'. template <class T1, class T2> pair(std::pair<T1, T2>) -> pair<T1, T2>; // Deduce the specified types 'T1' and 'T2' from the corresponding template // parameters of the 'std::pair' supplied to the constructor of 'pair'. template < class T1, class T2, class ALLOC, class = typename bsl::enable_if_t< bsl::is_convertible_v<ALLOC *, BloombergLP::bslma::Allocator *>> > pair(std::pair<T1, T2>, ALLOC *) -> pair<T1, T2>; // Deduce the specified types 'T1' and 'T2' from the corresponding template // parameters of the 'std::pair' supplied to the constructor of 'pair'. // This guide does not participate in deduction unless the specified // 'ALLOC' inherits from 'bslma::Allocator'. #endif // FREE OPERATORS template <class T1, class T2> inline BSLS_KEYWORD_CONSTEXPR bool operator==(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs); // Return true if the specified 'lhs' and 'rhs' pair objects have the same // value and false otherwise. 'lhs' has the same value as 'rhs' if // 'lhs.first == rhs.first' and 'lhs.second == rhs.second'. A call to this // operator will not compile unless both 'T1' and 'T2' supply 'operator=='. template <class T1, class T2> inline BSLS_KEYWORD_CONSTEXPR bool operator!=(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs); // Return true if the specified 'lhs' and 'rhs' pair objects do not have // the same value and false otherwise. 'lhs' does not have the same value // as 'rhs' if 'lhs == rhs' would return false. A call to this operator // will not compile unless a call to 'lhs == rhs' would compile. template <class T1, class T2> inline BSLS_KEYWORD_CONSTEXPR bool operator<(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs); // Return true if the specified 'lhs' has a value less than the specified // 'rhs' and false otherwise. Whether or not 'lhs' is less than 'rhs' is // determined by a lexicographical comparison of the 'first' and 'second' // data members of 'lhs' and 'rhs'. In other words: return true if // 'lhs.first < rhs.first' and false if 'rhs.first < lhs.first', otherwise // return 'lhs.second < rhs.second'. A call to this operator will not // compile unless both 'T1' and 'T2' supply 'operator<'. template <class T1, class T2> inline BSLS_KEYWORD_CONSTEXPR bool operator>(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs); // Return true if the specified 'lhs' has a value greater than the // specified 'rhs' and false otherwise. 'lhs' has a value greater than // 'rhs' if 'rhs' < 'lhs' would return true. A call to this operator will // not compile unless a call to 'lhs < rhs' would compile. template <class T1, class T2> inline BSLS_KEYWORD_CONSTEXPR bool operator<=(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs); // Return true if the specified 'lhs' has a value less than or equal to the // specified 'rhs' and false otherwise. 'lhs' has a value less than or // equal to 'rhs' if 'rhs' < 'lhs' would return false. A call to this // operator will not compile unless a call to 'lhs < rhs' would compile. template <class T1, class T2> inline BSLS_KEYWORD_CONSTEXPR bool operator>=(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs); // Return true if the specified 'lhs' has a value greater than or equal to // the specified 'rhs' and false otherwise. 'lhs' has a value greater than // or equal to 'rhs' if 'lhs' < 'rhs' would return false. A call to this // operator will not compile unless a call to 'lhs < rhs' would compile. // FREE FUNCTIONS template <class T1, class T2> #if defined(BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE) void #else typename bsl::enable_if<bsl::is_swappable<T1>::value && bsl::is_swappable<T2>::value>::type #endif swap(pair<T1, T2>& a, pair<T1, T2>& b) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(BSLS_KEYWORD_NOEXCEPT_OPERATOR(a.swap(b))); // Swap the values of the specified 'a' and 'b' pairs by applying 'swap' to // each of the 'first' and 'second' pair fields. Note that this method is // no-throw only if 'swap' on each field is no-throw. // HASH SPECIALIZATIONS template <class HASHALG, class T1, class T2> void hashAppend(HASHALG& hashAlg, const pair<T1, T2>& input); // Pass the specified 'input' to the specified 'hashAlg' } // close namespace bsl #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) namespace std { #if defined(BSLS_PLATFORM_CMP_CLANG) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmismatched-tags" #endif // ==================== // struct tuple_element // ==================== template<class T1, class T2> struct tuple_element<0, bsl::pair<T1, T2> > // This partial specialization of 'tuple_element' provides compile-time // access to the type of the pair's first element. { // TYPES typedef T1 type; }; template<class T1, class T2> struct tuple_element<1, bsl::pair<T1, T2> > // This partial specialization of 'tuple_element' provides compile-time // access to the type of the pair's second element. { // TYPES typedef T2 type; }; // ================= // struct tuple_size // ================= template<class T1, class T2> struct tuple_size<bsl::pair<T1, T2> > : integral_constant<size_t, 2> // This meta-function provides a compile-time way to obtain the number of // elements in a pair, which is always 2. {}; #if defined(BSLS_PLATFORM_CMP_CLANG) #pragma clang diagnostic pop #endif } // close namespace std namespace BloombergLP { namespace bslstl { // ===================== // class Pair_GetImpUtil // ===================== template <std::size_t INDEX, class T1, class T2> struct Pair_GetImpUtil // This utility class template provides functions for selecting the element // of pair, returned from 'bsl::get(bsl::pair<T1, T2>)', by its index. { BSLMF_ASSERT(INDEX < 2); }; template <class T1, class T2> struct Pair_GetImpUtil<0, T1, T2> // This partial specialization of 'Pair_GetImpUtil', for when the // (template parameter) 'INDEX'(element's index) is equal to 0. { private: // PRIVATE TYPES typedef bslmf::MovableRefUtil MovUtil; // This typedef is a convenient alias for the utility associated with // implementing movable references in C++03 and C++11 environments. public: // CLASS METHODS static T1& getPairElement(bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT; // Return a reference providing modifiable access to the first element // of the specified 'p'. static const T1& getPairElement(const bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT; // Return a reference providing non-modifiable access to the first // element of the specified 'p'. #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) static T1&& getPairElement(bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT; // Return a rvalue reference providing modifiable access to the first // element of the specified 'p' static const T1&& getPairElement(const bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT; // Return a rvalue reference providing non-modifiable access to the // first element of the specified 'p' #endif }; template <class T1, class T2> struct Pair_GetImpUtil<1u, T1, T2> // This partial specialization of 'Pair_GetImpUtil', for when the // (template parameter) 'INDEX'(element's index) is equal to 1. { private: // PRIVATE TYPES typedef bslmf::MovableRefUtil MovUtil; // This typedef is a convenient alias for the utility associated with // implementing movable references in C++03 and C++11 environments. public: // CLASS METHODS static T2& getPairElement(bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT; // Return a reference providing modifiable access to the second element // of the specified 'p'. static const T2& getPairElement(const bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT; // Return a reference providing non-modifiable access to the second // element of the specified 'p'. #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) static T2&& getPairElement(bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT; // Return a rvalue reference providing modifiable access to the second // element of the specified 'p' static const T2&& getPairElement(const bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT; // Return a rvalue reference providing non-modifiable access to the // second element of the specified 'p' #endif }; template <class T, class T1, class T2> struct Pair_IndexOfType // This meta-function provides a compile-time way to obtain the index of // 'bsl::pair' element, having the (template parameter) type 'T'. If // neither type of pair's element is equal to 'T' or both pair's elements // have the same type, code is not compiled. {}; template <class T1, class T2> struct Pair_IndexOfType<T1, T1, T2> : bsl::integral_constant<size_t, 0> // This partial specialization of 'Pair_IndexOfType' returns the index of // first element of pair. {}; template <class T1, class T2> struct Pair_IndexOfType<T2, T1, T2> : bsl::integral_constant<size_t, 1u> // This partial specialization of 'Pair_IndexOfType' returns the index of // second element of pair. {}; } // close package namespace } // close enterprise namespace namespace bsl { // FREE FUNCTIONS template<std::size_t INDEX, class T1, class T2> typename std::tuple_element<INDEX, bsl::pair<T1, T2> >::type& get(bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT; // Return a reference providing modifiable access to the element of the // specified 'p', having the ordinal number specified by the (template // parameter) 'INDEX'. This function will not compile unless the 'INDEX' // is either 0 or 1. template<std::size_t INDEX, class T1, class T2> const typename std::tuple_element<INDEX, bsl::pair<T1, T2> >::type& get(const bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT; // Return a reference providing non-modifiable access to the element of the // specified 'p', having the ordinal number specified by the (template // parameter) 'INDEX'. This function will not compile unless the 'INDEX' // is either 0 or 1. #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template<std::size_t INDEX, class T1, class T2> typename std::tuple_element<INDEX, bsl::pair<T1, T2> >::type&& get(bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT; // Return a rvalue reference providing modifiable access to the element of // the specified 'p', having the ordinal number specified by the (template // parameter) 'INDEX'. This function will not compile unless the 'INDEX' // is either 0 or 1. #endif template<class TYPE, class T1, class T2> TYPE& get(bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT; // Return a reference providing modifiable access to the element of the // specified 'p', having the (template parameter) 'TYPE'. This function // will not compile unless the types 'T1' and 'T2' are different and the // 'TYPE' is the same as either 'T1' or 'T2'. template<class TYPE, class T1, class T2> const TYPE& get(const bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT; // Return a reference providing non-modifiable access to the element of the // specified 'p', having the (template parameter) 'TYPE'. This function // will not compile unless the types 'T1' and 'T2' are different and the // 'TYPE' is the same as either 'T1' or 'T2'. #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template<class TYPE, class T1, class T2> TYPE&& get(bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT; // Return a rvalue reference providing modifiable access to the element of // the specified 'p', having the (template parameter) 'TYPE'. This // function will not compile unless the types 'T1' and 'T2' are different // and the 'TYPE' is the same as either 'T1' or 'T2'. template<class TYPE, class T1, class T2> const TYPE&& get(const bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT; // Return a rvalue reference providing non-modifiable access to the element // of the specified 'p', having the (template parameter) 'TYPE'. This // function will not compile unless the types 'T1' and 'T2' are different // and the 'TYPE' is the same as either 'T1' or 'T2'. #endif } // close bsl namespace #endif // ============================================================================ // INLINE FUNCTION DEFINITIONS // ============================================================================ // See IMPLEMENTATION NOTES in the .cpp before modifying anything below. namespace bsl { // ------------------- // struct Pair_ImpUtil // ------------------- #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) template <class ... ARGS> inline std::tuple<ARGS...> Pair_ImpUtil::concatAllocator( BSLS_COMPILERFEATURES_FORWARD_REF(std::tuple<ARGS...>) tpl, BloombergLP::bslma::Allocator *, bsl::Pair_BslmaIdiomNone) { return BloombergLP::bslmf::MovableRefUtil::move(tpl); } template <class ... ARGS> inline std::tuple<ARGS..., BloombergLP::bslma::Allocator *> Pair_ImpUtil::concatAllocator( BSLS_COMPILERFEATURES_FORWARD_REF(std::tuple<ARGS...>) tpl, BloombergLP::bslma::Allocator *alloc, bsl::Pair_BslmaIdiomAtEnd) { return std::tuple_cat(BloombergLP::bslmf::MovableRefUtil::move(tpl), std::tie(alloc)); } template <class ... ARGS> inline std::tuple<bsl::allocator_arg_t, BloombergLP::bslma::Allocator *, ARGS...> Pair_ImpUtil::concatAllocator( BSLS_COMPILERFEATURES_FORWARD_REF(std::tuple<ARGS...>) tpl, BloombergLP::bslma::Allocator *alloc, bsl::Pair_BslmaIdiomAllocatorArgT) { return std::tuple_cat(std::tie(bsl::allocator_arg, alloc), BloombergLP::bslmf::MovableRefUtil::move(tpl)); } #endif // ----------------- // struct Pair_First // ----------------- // CREATORS #if defined(BSLSTL_PAIR_DO_NOT_DEFAULT_THE_DEFAULT_CONSTRUCTOR) template <class TYPE> inline BSLS_KEYWORD_CONSTEXPR Pair_First<TYPE>::Pair_First() : first() { } #endif template <class TYPE> inline Pair_First<TYPE>::Pair_First(BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone) : first() { } template <class TYPE> inline Pair_First<TYPE>::Pair_First(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd) : first(basicAllocator) { } template <class TYPE> inline Pair_First<TYPE>::Pair_First(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT) : first(bsl::allocator_arg, basicAllocator) { } template <class TYPE> inline BSLS_KEYWORD_CONSTEXPR Pair_First<TYPE>::Pair_First( typename bsl::add_lvalue_reference<const TYPE>::type value) : first(value) { } #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class TYPE> template <class PARAM> inline BSLS_KEYWORD_CONSTEXPR Pair_First<TYPE>::Pair_First(PARAM&& value) : first(BSLS_COMPILERFEATURES_FORWARD(PARAM, value)) { } #else template <class TYPE> template <class PARAM> inline BSLS_KEYWORD_CONSTEXPR Pair_First<TYPE>::Pair_First(const PARAM& value) : first(value) { } template <class TYPE> template <class PARAM> inline BSLS_KEYWORD_CONSTEXPR Pair_First<TYPE>::Pair_First(PARAM& value) : first(value) { } #endif #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class TYPE> template <class PARAM> inline Pair_First<TYPE>::Pair_First(PARAM&& value, BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone) : first(BSLS_COMPILERFEATURES_FORWARD(PARAM,value)) { } template <class TYPE> template <class PARAM> inline Pair_First<TYPE>::Pair_First(PARAM&& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd) : first(BSLS_COMPILERFEATURES_FORWARD(PARAM, value), basicAllocator) { } template <class TYPE> template <class PARAM> inline Pair_First<TYPE>::Pair_First(PARAM&& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT) : first(bsl::allocator_arg, basicAllocator, BSLS_COMPILERFEATURES_FORWARD(PARAM, value)) { } #else template <class TYPE> template <class PARAM> inline Pair_First<TYPE>::Pair_First(const PARAM& value, BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone) : first(value) { } template <class TYPE> template <class PARAM> inline Pair_First<TYPE>::Pair_First(PARAM& value, BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone) : first(value) { } template <class TYPE> template <class PARAM> inline Pair_First<TYPE>::Pair_First(const PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd) : first(value, basicAllocator) { } template <class TYPE> template <class PARAM> inline Pair_First<TYPE>::Pair_First(PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd) : first(value, basicAllocator) { } template <class TYPE> template <class PARAM> inline Pair_First<TYPE>::Pair_First(const PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT) : first(bsl::allocator_arg, basicAllocator, value) { } template <class TYPE> template <class PARAM> inline Pair_First<TYPE>::Pair_First(PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT) : first(bsl::allocator_arg, basicAllocator, value) { } #endif #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \ && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE) template <class TYPE> template <class ...ARGS, size_t ...I> inline Pair_First<TYPE>::Pair_First(std::tuple<ARGS...>&& argsPack, BloombergLP::bslstl::Pair_IndexSequence<I...>) : first(std::get<I>(std::move(argsPack))...) { } #endif // ------------------------ // struct Pair_First<TYPE&> // ------------------------ // CREATORS template <class TYPE> BSLS_KEYWORD_CONSTEXPR inline Pair_First<TYPE&>::Pair_First(TYPE& value) : first(value) { } #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_First<TYPE&>::Pair_First(PARAM&& value) : first(std::forward<PARAM>(value)) { } #else template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_First<TYPE&>::Pair_First(const PARAM& value) : first(value) { } template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_First<TYPE&>::Pair_First(PARAM& value) : first(value) { } #endif #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_First<TYPE&>::Pair_First(PARAM&& value, BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone ) : first(std::forward<PARAM>(value)) { } #else template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_First<TYPE&>::Pair_First(const PARAM& value, BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone ) : first(value) { } template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_First<TYPE&>::Pair_First(PARAM& value, BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone ) : first(value) { } #endif #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \ && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE) template <class TYPE> template <class ARG> BSLS_KEYWORD_CONSTEXPR inline Pair_First<TYPE&>::Pair_First(std::tuple<ARG>&& arg, BloombergLP::bslstl::Pair_IndexSequence<0u>) : first(std::get<0u>(arg)) { } #endif // MANIPULATORS template <class TYPE> inline Pair_First<TYPE&>& Pair_First<TYPE&>::operator=(const Pair_First& rhs) BSLS_KEYWORD_NOEXCEPT { first = rhs.first; return *this; } #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) // ------------------------- // struct Pair_First<TYPE&&> // ------------------------- // CREATORS template <class TYPE> BSLS_KEYWORD_CONSTEXPR inline Pair_First<TYPE&&>::Pair_First(TYPE&& value) : first(std::move(value)) { } template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_First<TYPE&&>::Pair_First(PARAM&& value) : first(std::forward<PARAM>(value)) { } template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_First<TYPE&&>::Pair_First(PARAM&& value, BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone ) : first(std::forward<PARAM>(value)) { } #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \ && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE) template <class TYPE> template <class ARG> BSLS_KEYWORD_CONSTEXPR inline Pair_First<TYPE&&>::Pair_First(std::tuple<ARG>&& arg, BloombergLP::bslstl::Pair_IndexSequence<0u>) : first(std::get<0u>(arg)) { } #endif // MANIPULATORS template <class TYPE> inline Pair_First<TYPE&&>& Pair_First<TYPE&&>::operator=(const Pair_First& rhs) BSLS_KEYWORD_NOEXCEPT { first = rhs.first; return *this; } #endif // ------------------ // struct Pair_Second // ------------------ // CREATORS #if defined(BSLSTL_PAIR_DO_NOT_DEFAULT_THE_DEFAULT_CONSTRUCTOR) template <class TYPE> inline BSLS_KEYWORD_CONSTEXPR Pair_Second<TYPE>::Pair_Second() : second() { } #endif template <class TYPE> inline Pair_Second<TYPE>::Pair_Second(BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone) : second() { } template <class TYPE> inline Pair_Second<TYPE>::Pair_Second(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd) : second(basicAllocator) { } template <class TYPE> inline Pair_Second<TYPE>::Pair_Second(BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT) : second(bsl::allocator_arg, basicAllocator) { } template <class TYPE> inline BSLS_KEYWORD_CONSTEXPR Pair_Second<TYPE>::Pair_Second( typename bsl::add_lvalue_reference<const TYPE>::type value) : second(value) { } #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class TYPE> template <class PARAM> inline BSLS_KEYWORD_CONSTEXPR Pair_Second<TYPE>::Pair_Second(PARAM&& value) : second(BSLS_COMPILERFEATURES_FORWARD(PARAM, value)) { } #else template <class TYPE> template <class PARAM> inline BSLS_KEYWORD_CONSTEXPR Pair_Second<TYPE>::Pair_Second(const PARAM& value) : second(value) { } template <class TYPE> template <class PARAM> inline BSLS_KEYWORD_CONSTEXPR Pair_Second<TYPE>::Pair_Second(PARAM& value) : second(value) { } #endif #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class TYPE> template <class PARAM> inline Pair_Second<TYPE>::Pair_Second(PARAM&& value, BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone) : second(BSLS_COMPILERFEATURES_FORWARD(PARAM, value)) { } template <class TYPE> template <class PARAM> inline Pair_Second<TYPE>::Pair_Second(PARAM&& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd) : second(BSLS_COMPILERFEATURES_FORWARD(PARAM, value), basicAllocator) { } template <class TYPE> template <class PARAM> inline Pair_Second<TYPE>::Pair_Second(PARAM&& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT) : second(bsl::allocator_arg, basicAllocator, BSLS_COMPILERFEATURES_FORWARD(PARAM, value)) { } #else template <class TYPE> template <class PARAM> inline Pair_Second<TYPE>::Pair_Second(const PARAM& value, BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone) : second(value) { } template <class TYPE> template <class PARAM> inline Pair_Second<TYPE>::Pair_Second(PARAM& value, BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone) : second(value) { } template <class TYPE> template <class PARAM> inline Pair_Second<TYPE>::Pair_Second(const PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd) : second(value, basicAllocator) { } template <class TYPE> template <class PARAM> inline Pair_Second<TYPE>::Pair_Second(PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAtEnd) : second(value, basicAllocator) { } template <class TYPE> template <class PARAM> inline Pair_Second<TYPE>::Pair_Second(const PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT) : second(bsl::allocator_arg, basicAllocator, value) { } template <class TYPE> template <class PARAM> inline Pair_Second<TYPE>::Pair_Second(PARAM& value, BloombergLP::bslma::Allocator *basicAllocator, Pair_BslmaIdiomAllocatorArgT) : second(bsl::allocator_arg, basicAllocator, value) { } #endif #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \ && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE) template <class TYPE> template <class ...ARGS, size_t ...I> inline Pair_Second<TYPE>::Pair_Second(std::tuple<ARGS...>&& argsPack, BloombergLP::bslstl::Pair_IndexSequence<I...>) : second(std::get<I>(std::move(argsPack))...) { } #endif // ------------------------- // struct Pair_Second<TYPE&> // ------------------------- // CREATORS template <class TYPE> BSLS_KEYWORD_CONSTEXPR inline Pair_Second<TYPE&>::Pair_Second(TYPE& value) : second(value) { } #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_Second<TYPE&>::Pair_Second(PARAM&& value) : second(std::forward<PARAM>(value)) { } #else template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_Second<TYPE&>::Pair_Second(const PARAM& value) : second(value) { } template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_Second<TYPE&>::Pair_Second(PARAM& value) : second(value) { } #endif #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_Second<TYPE&>::Pair_Second(PARAM&& value, BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone ) : second(std::forward<PARAM>(value)) { } #else template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_Second<TYPE&>::Pair_Second(const PARAM& value, BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone ) : second(value) { } template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_Second<TYPE&>::Pair_Second(PARAM& value, BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone ) : second(value) { } #endif #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \ && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE) template <class TYPE> template <class ARG> BSLS_KEYWORD_CONSTEXPR inline Pair_Second<TYPE&>::Pair_Second(std::tuple<ARG>&& arg, BloombergLP::bslstl::Pair_IndexSequence<0u>) : second(std::get<0u>(arg)) { } #endif // MANIPULATORS template <class TYPE> inline Pair_Second<TYPE&>& Pair_Second<TYPE&>::operator=(const Pair_Second& rhs) BSLS_KEYWORD_NOEXCEPT { second = rhs.second; return *this; } #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) // -------------------------- // struct Pair_Second<TYPE&&> // -------------------------- // CREATORS template <class TYPE> BSLS_KEYWORD_CONSTEXPR Pair_Second<TYPE&&>::Pair_Second(TYPE&& value) : second(std::move(value)) { } template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_Second<TYPE&&>::Pair_Second(PARAM&& value) : second(std::forward<PARAM>(value)) { } template <class TYPE> template <class PARAM> BSLS_KEYWORD_CONSTEXPR inline Pair_Second<TYPE&&>::Pair_Second(PARAM&& value, BloombergLP::bslma::Allocator *, Pair_BslmaIdiomNone ) : second(std::forward<PARAM>(value)) { } #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) \ && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE) template <class TYPE> template <class ARG> BSLS_KEYWORD_CONSTEXPR inline Pair_Second<TYPE&&>::Pair_Second(std::tuple<ARG>&& arg, BloombergLP::bslstl::Pair_IndexSequence<0u>) : second(std::get<0u>(arg)) { } #endif // MANIPULATORS template <class TYPE> inline Pair_Second<TYPE&&>& Pair_Second<TYPE&&>::operator=(const Pair_Second& rhs) BSLS_KEYWORD_NOEXCEPT { second = rhs.second; return *this; } #endif // ---------- // class pair // ---------- // CREATORS #if defined(BSLSTL_PAIR_DO_NOT_DEFAULT_THE_DEFAULT_CONSTRUCTOR) template <class T1, class T2> inline BSLS_KEYWORD_CONSTEXPR pair<T1, T2>::pair() : FirstBase() , SecondBase() { } #endif template <class T1, class T2> inline pair<T1, T2>::pair(BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(basicAllocator, FirstBslmaIdiom()) , SecondBase(basicAllocator, SecondBslmaIdiom()) { } template <class T1, class T2> BSLS_KEYWORD_CONSTEXPR inline pair<T1, T2>::pair(typename bsl::add_lvalue_reference<const T1>::type a, typename bsl::add_lvalue_reference<const T2>::type b) : FirstBase(a) , SecondBase(b) { } template <class T1, class T2> inline pair<T1, T2>::pair( typename bsl::add_lvalue_reference<const T1>::type a, typename bsl::add_lvalue_reference<const T2>::type b, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(a, basicAllocator, FirstBslmaIdiom()) , SecondBase(b, basicAllocator, SecondBslmaIdiom()) { } #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class T1, class T2> template <class PARAM_1, class PARAM_2> inline pair<T1, T2>::pair(PARAM_1&& a, PARAM_2&& b, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(BSLS_COMPILERFEATURES_FORWARD(PARAM_1, a), basicAllocator, FirstBslmaIdiom()) , SecondBase(BSLS_COMPILERFEATURES_FORWARD(PARAM_2, b), basicAllocator, SecondBslmaIdiom()) { } #else template <class T1, class T2> template <class PARAM_1, class PARAM_2> inline pair<T1, T2>::pair(const PARAM_1& a, const PARAM_2& b, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(a, basicAllocator, FirstBslmaIdiom()) , SecondBase(b, basicAllocator, SecondBslmaIdiom()) { } template <class T1, class T2> template <class PARAM_1, class PARAM_2> inline pair<T1, T2>::pair(PARAM_1& a, const PARAM_2& b, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(a, basicAllocator, FirstBslmaIdiom()) , SecondBase(b, basicAllocator, SecondBslmaIdiom()) { } template <class T1, class T2> template <class PARAM_1, class PARAM_2> inline pair<T1, T2>::pair(const PARAM_1& a, PARAM_2& b, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(a, basicAllocator, FirstBslmaIdiom()) , SecondBase(b, basicAllocator, SecondBslmaIdiom()) { } template <class T1, class T2> template <class PARAM_1, class PARAM_2> inline pair<T1, T2>::pair(PARAM_1& a, PARAM_2& b, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(a, basicAllocator, FirstBslmaIdiom()) , SecondBase(b, basicAllocator, SecondBslmaIdiom()) { } #endif #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_PAIR_PIECEWISE_CONSTRUCTOR) \ && defined(BSLS_LIBRARYFEATURES_HAS_CPP14_INTEGER_SEQUENCE) template <class T1, class T2> template<class ...ARGS_1, class ...ARGS_2> inline pair<T1, T2>::pair(std::piecewise_construct_t, std::tuple<ARGS_1...> first_args, std::tuple<ARGS_2...> second_args) : FirstBase(std::move(first_args), typename BloombergLP::bslstl::Pair_MakeIndexSequence< std::tuple_size<std::tuple<ARGS_1...> >::value >()) , SecondBase(std::move(second_args), typename BloombergLP::bslstl::Pair_MakeIndexSequence< std::tuple_size<std::tuple<ARGS_2...> >::value >()) { } template <class T1, class T2> template<class ...ARGS_1, class ...ARGS_2> inline pair<T1, T2>::pair(std::piecewise_construct_t, std::tuple<ARGS_1...> first_args, std::tuple<ARGS_2...> second_args, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(Pair_ImpUtil::concatAllocator(std::move(first_args), basicAllocator, FirstBslmaIdiom()), typename BloombergLP::bslstl::Pair_MakeIndexSequence< Pair_ConstructionParametersPackLength<T1, ARGS_1...>::value>()) , SecondBase(Pair_ImpUtil::concatAllocator(std::move(second_args), basicAllocator, SecondBslmaIdiom()), typename BloombergLP::bslstl::Pair_MakeIndexSequence< Pair_ConstructionParametersPackLength<T2, ARGS_2...>::value>()) { } #endif template <class T1, class T2> inline pair<T1, T2>::pair(const pair& original, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(original.first, basicAllocator, FirstBslmaIdiom()) , SecondBase(original.second, basicAllocator, SecondBslmaIdiom()) { } #if defined (BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class T1, class T2> inline pair<T1, T2>::pair(pair&& original, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(BSLS_COMPILERFEATURES_FORWARD(T1, original.first), basicAllocator, FirstBslmaIdiom()) , SecondBase(BSLS_COMPILERFEATURES_FORWARD(T2, original.second), basicAllocator, SecondBslmaIdiom()) { } #else template <class T1, class T2> inline BSLS_KEYWORD_CONSTEXPR pair<T1, T2>::pair(BloombergLP::bslmf::MovableRef<pair> original) : FirstBase(MovUtil::move(MovUtil::access(original).first)) , SecondBase(MovUtil::move(MovUtil::access(original).second)) { } template <class T1, class T2> inline BSLS_KEYWORD_CONSTEXPR pair<T1, T2>::pair(BloombergLP::bslmf::MovableRef<pair> original, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(MovUtil::move(MovUtil::access(original).first), basicAllocator, FirstBslmaIdiom()) , SecondBase(MovUtil::move(MovUtil::access(original).second), basicAllocator, SecondBslmaIdiom()) { } #endif #if defined(BSLSTL_PAIR_ENABLE_ALL_CONVERTIBILITY_CHECKS) template <class T1, class T2> template <class PARAM_1, class PARAM_2> inline BSLS_KEYWORD_CONSTEXPR pair<T1, T2>::pair( const pair<PARAM_1, PARAM_2>& other, typename bsl::enable_if<bsl::is_convertible<PARAM_1, T1>::value && bsl::is_convertible<PARAM_2, T2>::value, void *>::type) : FirstBase(other.first) , SecondBase(other.second) { } template <class T1, class T2> template <class PARAM_1, class PARAM_2> inline BSLS_KEYWORD_CONSTEXPR pair<T1, T2>::pair( const 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, void *>::type) : FirstBase(other.first) , SecondBase(other.second) { } #else template <class T1, class T2> template <class PARAM_1, class PARAM_2> inline BSLS_KEYWORD_CONSTEXPR pair<T1, T2>::pair(const pair<PARAM_1, PARAM_2>& other) : FirstBase(other.first) , SecondBase(other.second) { } template <class T1, class T2> template <class PARAM_1, class PARAM_2> inline BSLS_KEYWORD_CONSTEXPR pair<T1, T2>::pair(const std::pair<PARAM_1, PARAM_2>& other) : FirstBase(other.first) , SecondBase(other.second) { } #endif template <class T1, class T2> template <class PARAM_1, class PARAM_2> inline pair<T1, T2>::pair(const pair<PARAM_1, PARAM_2>& other, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(other.first, basicAllocator, FirstBslmaIdiom()) , SecondBase(other.second, basicAllocator, SecondBslmaIdiom()) { } template <class T1, class T2> template <class PARAM_1, class PARAM_2> inline pair<T1, T2>::pair(const std::pair<PARAM_1, PARAM_2>& other, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(other.first, basicAllocator, FirstBslmaIdiom()) , SecondBase(other.second, basicAllocator, SecondBslmaIdiom()) { } #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class T1, class T2> template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair<T1, T2>::pair( pair<PARAM_1, PARAM_2>&& other, typename bsl::enable_if<bsl::is_convertible<PARAM_1, T1>::value && bsl::is_convertible<PARAM_2, T2>::value, void *>::type) : FirstBase(MovUtil::move(other.first)) , SecondBase(MovUtil::move(other.second)) { } template <class T1, class T2> template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair<T1, T2>::pair( 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, void *>::type) : FirstBase(MovUtil::move(other.first)) , SecondBase(MovUtil::move(other.second)) { } template <class T1, class T2> template <class PARAM_1, class PARAM_2> pair<T1, T2>::pair(pair<PARAM_1, PARAM_2>&& other, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(MovUtil::move(other.first), basicAllocator, FirstBslmaIdiom()) , SecondBase(MovUtil::move(other.second), basicAllocator, SecondBslmaIdiom()) { } template <class T1, class T2> template <class PARAM_1, class PARAM_2> pair<T1, T2>::pair(std::pair<PARAM_1, PARAM_2>&& other, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(MovUtil::move(other.first), basicAllocator, FirstBslmaIdiom()) , SecondBase(MovUtil::move(other.second), basicAllocator, SecondBslmaIdiom()) { } #else template <class T1, class T2> template <class PARAM_1, class PARAM_2> pair<T1, T2>::pair( BloombergLP::bslmf::MovableRef<pair<PARAM_1, PARAM_2> > other, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(MovUtil::move(MovUtil::access(other).first), basicAllocator, FirstBslmaIdiom()) , SecondBase(MovUtil::move(MovUtil::access(other).second), basicAllocator, SecondBslmaIdiom()) { } template <class T1, class T2> template <class PARAM_1, class PARAM_2> pair<T1, T2>::pair( BloombergLP::bslmf::MovableRef<std::pair<PARAM_1, PARAM_2> > other, BloombergLP::bslma::Allocator *basicAllocator) : FirstBase(MovUtil::move(MovUtil::access(other).first), basicAllocator, FirstBslmaIdiom()) , SecondBase(MovUtil::move(MovUtil::access(other).second), basicAllocator, SecondBslmaIdiom()) { } #endif #ifndef BDE_OMIT_INTERNAL_DEPRECATED template <class T1, class T2> template <class PARAM_1, class PARAM_2> BSLS_KEYWORD_CONSTEXPR pair<T1, T2>::pair( const BloombergLP::bslma::ManagedPtr_PairProxy<PARAM_1, PARAM_2>& rhs) : FirstBase(rhs.first) , SecondBase(rhs.second) { } #endif // BDE_OMIT_INTERNAL_DEPRECATED // MANIPULATORS #if !defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class T1, class T2> pair<T1, T2>& pair<T1, T2>::operator=(BloombergLP::bslmf::MovableRef<pair> rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(false) { pair& lvalue = rhs; first = MovUtil::move(lvalue.first); second = MovUtil::move(lvalue.second); return *this; } #endif template <class T1, class T2> template <class PARAM_1, class PARAM_2> inline pair<T1, T2>& pair<T1, T2>::operator=(const pair<PARAM_1, PARAM_2>& rhs) { first = rhs.first; second = rhs.second; return *this; } #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class T1, class T2> template <class PARAM_1, class PARAM_2> pair<T1, T2>& pair<T1, T2>::operator=(pair<PARAM_1, PARAM_2>&& rhs) { first = MovUtil::move(rhs.first); second = MovUtil::move(rhs.second); return *this; } #else template <class T1, class T2> template <class PARAM_1, class PARAM_2> pair<T1, T2>& pair<T1, T2>::operator=( BloombergLP::bslmf::MovableRef<pair<PARAM_1, PARAM_2> > rhs) { pair<PARAM_1, PARAM_2>& lvalue = rhs; first = MovUtil::move(lvalue.first); second = MovUtil::move(lvalue.second); return *this; } #endif template <class T1, class T2> template <class PARAM_1, class PARAM_2> inline pair<T1, T2>& pair<T1, T2>::operator=(const std::pair<PARAM_1, PARAM_2>& rhs) { first = rhs.first; second = rhs.second; return *this; } #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) template <class T1, class T2> template <class PARAM_1, class PARAM_2, typename bsl::enable_if<bsl::is_convertible<T1, PARAM_1>::value && bsl::is_convertible<T2, PARAM_2>::value, bool>::type> inline pair<T1, T2>::operator std::tuple<PARAM_1&, PARAM_2&>() BSLS_KEYWORD_NOEXCEPT { return std::tuple<PARAM_1&, PARAM_2&>(first, second); } template <class T1, class T2> template <class PARAM_1, typename bsl::enable_if<bsl::is_convertible<T1, PARAM_1>::value, bool>::type> inline pair<T1, T2>::operator std::tuple<PARAM_1&, decltype(std::ignore)&>() BSLS_KEYWORD_NOEXCEPT { return std::tuple<PARAM_1&, decltype(std::ignore)&>(first, std::ignore); } template <class T1, class T2> template <class PARAM_2, typename bsl::enable_if<bsl::is_convertible<T2, PARAM_2>::value, bool>::type> inline pair<T1, T2>::operator std::tuple<decltype(std::ignore)&, PARAM_2&>() BSLS_KEYWORD_NOEXCEPT { return std::tuple<decltype(std::ignore)&, PARAM_2&>(std::ignore, second); } #endif template <class T1, class T2> inline #if defined(BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE) void pair<T1, T2>::swap(pair& other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(Pair_ImpUtil::hasNothrowSwap<T1, T2>()) #else void pair<T1, T2>::swap(pair& other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(bsl::is_nothrow_swappable<T1>::value && bsl::is_nothrow_swappable<T2>::value) #endif { // Find either 'std::swap' or a specialized 'swap' for 'T1' and 'T2' via // ADL. using std::swap; swap(first, other.first); swap(second, other.second); } // FREE OPERATORS template <class T1, class T2> inline BSLS_KEYWORD_CONSTEXPR bool operator==(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs) { return lhs.first == rhs.first && lhs.second == rhs.second; } template <class T1, class T2> inline BSLS_KEYWORD_CONSTEXPR bool operator!=(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs) { return ! (lhs == rhs); } template <class T1, class T2> inline BSLS_KEYWORD_CONSTEXPR bool operator<(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs) { return (lhs.first < rhs.first ? true : rhs.first < lhs.first ? false : lhs.second < rhs.second); } template <class T1, class T2> inline BSLS_KEYWORD_CONSTEXPR bool operator>(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs) { return rhs < lhs; } template <class T1, class T2> inline BSLS_KEYWORD_CONSTEXPR bool operator<=(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs) { return ! (rhs < lhs); } template <class T1, class T2> inline BSLS_KEYWORD_CONSTEXPR bool operator>=(const pair<T1, T2>& lhs, const pair<T1, T2>& rhs) { return ! (lhs < rhs); } // FREE FUNCTIONS template <class T1, class T2> inline #if defined(BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE) void #else typename bsl::enable_if<bsl::is_swappable<T1>::value && bsl::is_swappable<T2>::value>::type #endif swap(pair<T1, T2>& a, pair<T1, T2>& b) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(noexcept(a.swap(b))) { a.swap(b); } // HASH SPECIALIZATIONS template <class HASHALG, class T1, class T2> void hashAppend(HASHALG& hashAlg, const pair<T1, T2>& input) { using ::BloombergLP::bslh::hashAppend; hashAppend(hashAlg, input.first); hashAppend(hashAlg, input.second); } } // close namespace bsl #if defined(BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE) namespace BloombergLP { namespace bslstl { // --------------------- // class Pair_GetImpUtil // --------------------- // CLASS METHODS template <class T1, class T2> inline T1& Pair_GetImpUtil<0, T1, T2>::getPairElement(bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT { return p.first; } template <class T1, class T2> inline const T1& Pair_GetImpUtil<0, T1, T2>::getPairElement(const bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT { return p.first; } #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class T1, class T2> inline T1&& Pair_GetImpUtil<0, T1, T2>::getPairElement(bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT { return std::move(p.first); } template <class T1, class T2> inline const T1&& Pair_GetImpUtil<0, T1, T2>::getPairElement(const bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT { return std::move(p.first); } #endif template <class T1, class T2> inline T2& Pair_GetImpUtil<1u, T1, T2>::getPairElement(bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT { return p.second; } template <class T1, class T2> inline const T2& Pair_GetImpUtil<1u, T1, T2>::getPairElement(const bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT { return p.second; } #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template <class T1, class T2> inline T2&& Pair_GetImpUtil<1u, T1, T2>::getPairElement(bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT { return std::move(p.second); } template <class T1, class T2> inline const T2&& Pair_GetImpUtil<1u, T1, T2>::getPairElement(const bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT { return std::move(p.second); } #endif } // close package namespace } // close enterprise namespace // FREE FUNCTIONS template<std::size_t INDEX, class T1, class T2> inline typename std::tuple_element<INDEX, bsl::pair<T1, T2> >::type& bsl::get(bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT { return BloombergLP::bslstl::Pair_GetImpUtil<INDEX, T1, T2>::getPairElement( p); } template<std::size_t INDEX, class T1, class T2> inline const typename std::tuple_element<INDEX, bsl::pair<T1, T2> >::type& bsl::get(const bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT { return BloombergLP::bslstl::Pair_GetImpUtil<INDEX, T1, T2>::getPairElement( p); } #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template<std::size_t INDEX, class T1, class T2> inline typename std::tuple_element<INDEX, bsl::pair<T1, T2> >::type&& bsl::get(bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT { return BloombergLP::bslstl::Pair_GetImpUtil<INDEX, T1, T2>::getPairElement( std::move(p)); } #endif template<class TYPE, class T1, class T2> inline TYPE& bsl::get(bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT { return BloombergLP::bslstl::Pair_GetImpUtil< BloombergLP::bslstl::Pair_IndexOfType<TYPE, T1, T2>::value, T1, T2> ::getPairElement(p); } template<class TYPE, class T1, class T2> inline const TYPE& bsl::get(const bsl::pair<T1, T2>& p) BSLS_KEYWORD_NOEXCEPT { return BloombergLP::bslstl::Pair_GetImpUtil< BloombergLP::bslstl::Pair_IndexOfType<TYPE, T1, T2>::value, T1, T2> ::getPairElement(p); } #if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES) template<class TYPE, class T1, class T2> inline TYPE&& bsl::get(bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT { return BloombergLP::bslstl::Pair_GetImpUtil< BloombergLP::bslstl::Pair_IndexOfType<TYPE, T1, T2>::value, T1, T2> ::getPairElement(std::move(p)); } template<class TYPE, class T1, class T2> inline const TYPE&& bsl::get(const bsl::pair<T1, T2>&& p) BSLS_KEYWORD_NOEXCEPT { return BloombergLP::bslstl::Pair_GetImpUtil< BloombergLP::bslstl::Pair_IndexOfType<TYPE, T1, T2>::value, T1, T2> ::getPairElement(std::move(p)); } #endif // BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES #endif // BSLS_LIBRARYFEATURES_HAS_CPP11_TUPLE // ============================================================================ // TYPE TRAITS // ============================================================================ namespace bsl { template <class T1, class T2> struct is_trivially_copyable<pair<T1, T2> > : bsl::integral_constant<bool, is_trivially_copyable<T1>::value && is_trivially_copyable<T2>::value> {}; template <class T1, class T2> struct is_trivially_default_constructible<bsl::pair<T1, T2> > : bsl::integral_constant<bool, is_trivially_default_constructible<T1>::value && is_trivially_default_constructible<T2>::value> {}; } // close namespace bsl namespace BloombergLP { namespace bslmf { template <class T1, class T2> struct IsPair<bsl::pair<T1, T2> > : bsl::true_type {}; // Note that we must explicitly declare bitwise moveable sine 'T1' or 'T2' may // be bitwise moveable and not bitwise copyable. template <class T1, class T2> struct IsBitwiseMoveable<bsl::pair<T1, T2> > : bsl::integral_constant<bool, bslmf::IsBitwiseMoveable<T1>::value && bslmf::IsBitwiseMoveable<T2>::value> {}; template <class T1, class T2> struct IsBitwiseEqualityComparable<bsl::pair<T1, T2> > : bsl::integral_constant<bool, bslmf::IsBitwiseEqualityComparable<T1>::value && bslmf::IsBitwiseEqualityComparable<T2>::value && sizeof(T1) + sizeof(T2) == sizeof(bsl::pair<T1, T2>)> {}; } // close namespace bslmf namespace bslma { template <class T1, class T2> struct UsesBslmaAllocator<bsl::pair<T1, T2> > : bsl::integral_constant<bool, UsesBslmaAllocator<T1>::value || UsesBslmaAllocator<T2>::value> {}; } // close namespace bslma } // close enterprise namespace #ifdef BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE #undef BSLSTL_PAIR_DO_NOT_SFINAE_TEST_IS_SWAPPABLE #endif #endif // ---------------------------------------------------------------------------- // Copyright 2013 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------