// bslalg_arrayprimitives_cpp03.h -*-C++-*- // Automatically generated file. **DO NOT EDIT** #ifndef INCLUDED_BSLALG_ARRAYPRIMITIVES_CPP03 #define INCLUDED_BSLALG_ARRAYPRIMITIVES_CPP03 //@PURPOSE: Provide C++03 implementation for bslalg_arrayprimitives.h // //@CLASSES: See bslalg_arrayprimitives.h for list of classes // //@SEE_ALSO: bslalg_arrayprimitives // //@DESCRIPTION: This component is the C++03 translation of a C++11 component, // generated by the 'sim_cpp11_features.pl' program. If the original header // contains any specially delimited regions of C++11 code, then this generated // file contains the C++03 equivalent, i.e., with variadic templates expanded // and rvalue-references replaced by 'bslmf::MovableRef' objects. The header // code in this file is designed to be '#include'd into the original header // when compiling with a C++03 compiler. If there are no specially delimited // regions of C++11 code, then this header contains no code and is not // '#include'd in the original header. // // Generated on Wed Feb 1 13:02:05 2023 // Command line: sim_cpp11_features.pl bslalg_arrayprimitives.h #ifdef COMPILING_BSLALG_ARRAYPRIMITIVES_H #if defined(BSLS_PLATFORM_CMP_IBM) // IBM needs specific workarounds. # define BSLALG_ARRAYPRIMITIVES_CANNOT_REMOVE_POINTER_FROM_FUNCTION_POINTER 1 // xlC has problem removing pointer from function pointer types. # define BSLALG_ARRAYPRIMITIVES_NON_ZERO_NULL_VALUE_FOR_MEMBER_POINTERS 1 // xlC representation for a null member pointer is not all zero bits. #endif namespace BloombergLP { namespace bslalg { struct ArrayPrimitives_Imp; // ====================== // struct ArrayPrimitives // ====================== struct ArrayPrimitives { // This 'struct' provides a namespace for a suite of independent utility // functions that operate on arrays of elements of parameterized type // 'TARGET_TYPE'. Depending on the traits of 'TARGET_TYPE', the default // and copy constructors, destructor, assignment operators, etcetera may // not be invoked, optimized away by no-op or bit-wise move or copy. public: // TYPES typedef ArrayPrimitives_Imp Imp; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; // CLASS METHODS template <class ALLOCATOR, class FWD_ITER> static void copyConstruct( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, FWD_ITER fromBegin, FWD_ITER fromEnd, ALLOCATOR allocator); template <class ALLOCATOR, class SOURCE_TYPE> static void copyConstruct( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, SOURCE_TYPE *fromBegin, SOURCE_TYPE *fromEnd, ALLOCATOR allocator); // Copy the elements of type 'allocator_traits<ALLOCATOR>::value_type' // in the range beginning at the specified 'fromBegin' location and // ending immediately before the specified 'fromEnd' location into the // uninitialized array beginning at the specified 'toBegin' location, // using the specified 'allocator' to supply memory (if required). If // a constructor throws an exception during this operation, the output // array is left in an uninitialized state. The behavior is undefined // unless 'toBegin' refers to space sufficient to hold // 'fromEnd - fromBegin' elements. template <class TARGET_TYPE, class FWD_ITER> static void copyConstruct(TARGET_TYPE *toBegin, FWD_ITER fromBegin, FWD_ITER fromEnd, bslma::Allocator *allocator); template <class TARGET_TYPE, class SOURCE_TYPE> static void copyConstruct(TARGET_TYPE *toBegin, SOURCE_TYPE *fromBegin, SOURCE_TYPE *fromEnd, bslma::Allocator *allocator); // Copy into an uninitialized array of (the template parameter) // 'TARGET_TYPE' beginning at the specified 'toBegin' address, the // elements in the array of 'TARGET_TYPE' starting at the specified // 'fromBegin' address and ending immediately before the specified // 'fromEnd' address. If the (template parameter) 'ALLOCATOR' type is // derived from 'bslma::Allocator' and 'TARGET_TYPE' supports 'bslma' // allocators, then the specified 'allocator' is passed to each // invocation of the 'TARGET_TYPE' copy constructor. If a // 'TARGET_TYPE' constructor throws an exception during the operation, // then the destructor is called on any newly-constructed elements, // leaving the output array in an uninitialized state. template <class ALLOCATOR> static void moveConstruct( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator); // Move the elements of type 'allocator_traits<ALLOCATOR>::value_type' // in the range beginning at the specified 'fromBegin' location and // ending immediately before the specified 'fromEnd' location into the // uninitialized array beginning at the specified 'toBegin' location, // using the specified 'allocator' to supply memory (if required). The // elements in the input array are left in a valid but unspecified // state. If a constructor throws an exception during this operation, // the output array is left in an uninitialized state. The behavior is // undefined unless 'toBegin' refers to space sufficient to hold // 'fromEnd - fromBegin' elements. template <class TARGET_TYPE> static void moveConstruct(TARGET_TYPE *toBegin, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, bslma::Allocator *allocator); // Move the elements of the (template parameter) 'TARGET_TYPE' starting // at the specified 'fromBegin' address and ending immediately before // the specified 'fromEnd' address into the uninitialized array of // 'TARGET_TYPE' beginning at the specified 'toBegin' address, using // the specified 'allocator' to supply memory (if required). The // elements in the input array are left in a valid but unspecified // state. If a constructor throws an exception during this operation, // the output array is left in an uninitialized state. The behavior is // undefined unless 'toBegin' refers to space sufficient to hold // 'fromEnd - fromBegin' elements. template <class ALLOCATOR> static void defaultConstruct( typename bsl::allocator_traits<ALLOCATOR>::pointer begin, size_type numElements, ALLOCATOR allocator); // Value-inititalize the specified 'numElements' objects of type // 'allocator_traits<ALLOCATOR>::value_type' into the uninitialized // array beginning at the specified 'begin' location, using the // specified 'allocator' to supply memory (if required). If a // constructor throws an exception during this operation, then the // destructor is called on any newly constructed elements, leaving the // output array in an uninitialized state. The behavior is undefined // unless the 'begin' refers to space sufficient to hold 'numElements'. template <class TARGET_TYPE> static void defaultConstruct(TARGET_TYPE *begin, size_type numElements, bslma::Allocator *allocator); // Construct each of the elements of an array of the specified // 'numElements' of the parameterized 'TARGET_TYPE' starting at the // specified 'begin' address by value-initialization. If the (template // parameter) 'ALLOCATOR' type is derived from 'bslma::Allocator' and // 'TARGET_TYPE' supports 'bslma' allocators, then the specified // 'allocator' is passed to each 'TARGET_TYPE' default constructor // call. The behavior is undefined unless the output array contains at // least 'numElements' uninitialized elements after 'begin'. If a // 'TARGET_TYPE' constructor throws an exception during this operation, // then the destructor is called on any newly-constructed elements, // leaving the output array in an uninitialized state. template <class ALLOCATOR> static void destructiveMove( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator); // Move the elements of type 'allocator_traits<ALLOCATOR>::value_type' // in the range beginning at the specified 'fromBegin' location and // ending immediately before the specified 'fromEnd' location into the // uninitialized array beginning at the specified 'toBegin' location, // using the specified 'allocator' to supply memory (if required). On // return, the elements in the input range are invalid, i.e., their // destructors must not be called after this operation returns. If a // constructor throws an exception during this operation, the output // array is left in an uninitialized state. If a constructor other // than the move constructor of a non-copy-constructible type throws // an exception during this operation, the input array is unaffected; // otherwise, if the move constructor of a non-copy-constructible type // throws an exception during this operation, the input array is left // in a valid but unspecified state. The behavior is undefined unless // 'toBegin' refers to space sufficient to hold 'fromEnd - fromBegin' // elements. template <class TARGET_TYPE> static void destructiveMove(TARGET_TYPE *toBegin, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, bslma::Allocator *allocator); // Move the elements of the parameterized 'TARGET_TYPE' in the array // starting at the specified 'fromBegin' address and ending immediately // before the specified 'fromEnd' address into an uninitialized array // of 'TARGET_TYPE' beginning at the specified 'toBegin' address. On // return, the elements in the input range are invalid, i.e., their // destructors must not be called after this operation returns. If the // parameterized 'ALLOCATOR' type is derived from 'bslma::Allocator' // and 'TARGET_TYPE' supports 'bslma' allocators, then the specified // 'allocator' is used by the objects in their new location. If an // exception is thrown by a 'TARGET_TYPE' constructor during the // operation, then the output array is left in an uninitialized state // and the input elements remain in their original state. #if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES // {{{ BEGIN GENERATED CODE // Command line: sim_cpp11_features.pl bslalg_arrayprimitives.h #ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT #define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT 10 #endif #ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A #define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT #endif #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 0 template <class ALLOCATOR> static void destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 0 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 1 template <class ALLOCATOR, class ARGS_01> static void destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 1 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 2 template <class ALLOCATOR, class ARGS_01, class ARGS_02> static void destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 2 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 3 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03> static void destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 3 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 4 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04> static void destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 4 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 5 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05> static void destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 5 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 6 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06> static void destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 6 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 7 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07> static void destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 7 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 8 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08> static void destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 8 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 9 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09> static void destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 9 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 10 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09, class ARGS_10> static void destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_A >= 10 #else // The generated code below is a workaround for the absence of perfect // forwarding in some compilers. template <class ALLOCATOR, class... ARGS> static void destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments); // }}} END GENERATED CODE #endif template <class ALLOCATOR> static void destructiveMoveAndInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, size_type numElements, ALLOCATOR allocator); // Move the elements of type 'allocator_traits<ALLOCATOR>::value_type' // in the range beginning at the specified 'fromBegin' location and // ending immediately before the specified 'fromEnd' location into the // uninitialized array beginning at the specified 'toBegin' location // using the specified 'allocator' to supply memory (if required), // inserting at the specified 'position' (after translating from // 'fromBegin' to 'toBegin') the specified 'numElements' objects // initialized to default values, ensuring that the specified // 'fromEndPtr' points to the first uninitialized element in // '[fromBegin .. fromEnd)' as the elements are moved from source to // destination. On return, the elements in the input range are // invalid, i.e., their destructors must not be called after this // operation returns. If a constructor throws an exception during this // operation, the output array is left in an uninitialized state. If a // default constructor throws an exception, the input array is // unaffected; otherwise, if a (copy or move) constructor throws an // exception during this operation, the input elements in the range // '[fromBegin .. *fromEndPtr)' are left in a valid but unspecified // state and the remaining portion of the input array is left in an // uninitialized state. The behavior is undefined unless 'fromBegin <= // position <= fromEnd' and 'toBegin' refers to space sufficient to // hold 'fromEnd - fromBegin + 1' elements. template <class TARGET_TYPE> static void destructiveMoveAndInsert(TARGET_TYPE *toBegin, TARGET_TYPE **fromEndPtr, TARGET_TYPE *fromBegin, TARGET_TYPE *position, TARGET_TYPE *fromEnd, size_type numElements, bslma::Allocator *allocator); // Move the elements of the (template parameter) 'TARGET_TYPE' in the // starting at the specified 'fromBegin' address and ending immediately // before the specified 'fromEnd' address into the uninitialized array // beginning at the specified 'toBegin' location using the specified // 'allocator' to supply memory (if required), inserting at the // specified 'position' (after translating from 'fromBegin' to // 'toBegin') 'numElements' objects initialized to default values, // ensuring that the specified 'fromEndPtr' points to the first // uninitialized element in '[fromBegin .. fromEnd)' as the elements // are moved from source to destination. On return, the elements in // the input range are invalid, i.e., their destructors must not be // called after this operation returns. If a constructor throws an // exception during this operation, the output array is left in an // uninitialized state. If a default constructor throws an exception, // the input array is unaffected; otherwise, if a (copy or move) // constructor throws an exception during this operation, the input // elements in the range '[fromBegin .. *fromEndPtr)' are left in a // valid but unspecified state and the remaining portion of the input // array is left in an uninitialized state. The behavior is undefined // unless 'fromBegin <= position <= fromEnd' and 'toBegin' refers to // space sufficient to hold 'fromEnd - fromBegin + numElements' // elements. template <class ALLOCATOR> static void destructiveMoveAndInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, const typename bsl::allocator_traits<ALLOCATOR>::value_type& value, size_type numElements, ALLOCATOR allocator); // Move the elements of type 'allocator_traits<ALLOCATOR>::value_type' // in the range beginning at the specified 'fromBegin' location and // ending immediately before the specified 'fromEnd' location into the // uninitialized array beginning at the specified 'toBegin' location // using the specified 'allocator' to supply memory (if required), // inserting at the specified 'position' (after translating from // 'fromBegin' to 'toBegin') the specified 'numElements' copies of the // specified 'value', ensuring that the specified 'fromEndPtr' points // to the first uninitialized element in '[fromBegin .. fromEnd)' as // the elements are moved from source to destination. On return, the // elements in the input range are invalid, i.e., their destructors // must not be called after this operation returns. If a constructor // throws an exception during this operation, the output array is left // in an uninitialized state. If a (copy or move) constructor throws // an exception during this operation, the input elements in the range // '[fromBegin .. *fromEndPtr)' are left in a valid but unspecified // state and the remaining portion of the input array is left in an // uninitialized state. The behavior is undefined unless // 'fromBegin <= position <= fromEnd' and 'toBegin' refers to space // sufficient to hold 'fromEnd - fromBegin + numElements' elements. template <class TARGET_TYPE> static void destructiveMoveAndInsert(TARGET_TYPE *toBegin, TARGET_TYPE **fromEndPtr, TARGET_TYPE *fromBegin, TARGET_TYPE *position, TARGET_TYPE *fromEnd, const TARGET_TYPE& value, size_type numElements, bslma::Allocator *allocator); // Move the elements of the parameterized 'TARGET_TYPE' in the array // starting at the specified 'fromBegin' address and ending immediately // before the specified 'fromEnd' address into an uninitialized array // of 'TARGET_TYPE' at the specified 'toBegin' address, inserting at // the specified 'position' (after translating from 'fromBegin' to // 'toBegin') the specified 'numElements' copies of the specified // 'value'. Keep the pointer at the specified 'fromEndPtr' address // pointing to the first uninitialized element in '[ fromBegin, // fromEnd)' as the elements are moved from source to destination. The // behavior is undefined unless 'fromBegin <= position <= fromEnd' and // the destination array contains at least // '(fromEnd - fromBegin) + numElements' uninitialized elements. If a // copy constructor or assignment operator for 'TARGET_TYPE' throws an // exception, then any elements created in the output array are // destroyed and the elements in the range '[ fromBegin, *fromEndPtr )' // will have unspecified but valid values. template <class ALLOCATOR, class FWD_ITER> static void destructiveMoveAndInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, FWD_ITER first, FWD_ITER last, size_type numElements, ALLOCATOR allocator); // Move the elements of type 'allocator_traits<ALLOCATOR>::value_type' // in the range beginning at the specified 'fromBegin' location and // ending immediately before the specified 'fromEnd' location into the // uninitialized array beginning at the specified 'toBegin' location // using the specified 'allocator' to supply memory (if required), // inserting at the specified 'position' (after translating from // 'fromBegin' to 'toBegin') the specified 'numElements' copies of the // non-modifiable elements from the range starting at the specified // 'first' iterator of (template parameter) type 'FWD_ITER' and ending // immediately before the specified 'last' iterator, ensuring that the // specified 'fromEndPtr' points to the first uninitialized element in // '[fromBegin .. fromEnd)' as the elements are moved from source to // destination. On return, the elements in the input range are // invalid, i.e., their destructors must not be called after this // operation returns. If a constructor throws an exception during this // operation, the output array is left in an uninitialized state. If // a constructor other than the copy or move constructor throws an // exception during this operation, the input array is unaffected; // otherwise, if a copy or move constructor throws an exception during // this operation, the input elements in the range // '[fromBegin .. *fromEndPtr)' are left in a valid but unspecified // state and the remaining portion of the input array is left in an // uninitialized state. The behavior is undefined unless // 'fromBegin <= position <= fromEnd' and 'toBegin' refers to space // sufficient to hold 'fromEnd - fromBegin + numElements' elements. template <class TARGET_TYPE, class FWD_ITER> static void destructiveMoveAndInsert(TARGET_TYPE *toBegin, TARGET_TYPE **fromEndPtr, TARGET_TYPE *fromBegin, TARGET_TYPE *position, TARGET_TYPE *fromEnd, FWD_ITER first, FWD_ITER last, size_type numElements, bslma::Allocator *allocator); // Move the elements of the parameterized 'TARGET_TYPE' in the array // starting at the specified 'fromBegin' address and ending immediately // before the specified 'fromEnd' address into an uninitialized array // of 'TARGET_TYPE' at the specified 'toBegin' address, inserting at // the specified 'position' (after translating from 'fromBegin' to // 'toBegin') the specified 'numElements' copies of the non-modifiable // elements from the range starting at the specified 'first' iterator // of the parameterized 'FWD_ITER' type and ending immediately before // the specified 'last' iterator. Keep the pointer at the specified // 'fromEndPtr' to point to the first uninitialized element in // '[fromBegin, fromEnd)' as the elements are moved from source to // destination. The behavior is undefined unless // 'fromBegin <= position <= fromEnd', the destination array contains // at least '(fromEnd - fromBegin) + numElements' uninitialized // elements after 'toBegin', and 'numElements' is the distance from // 'first' to 'last'. If a copy constructor or assignment operator for // 'TARGET_TYPE' throws an exception, then any elements created in the // output array are destroyed and the elements in the range // '[ fromBegin, *fromEndPtr )' will have unspecified but valid values. template <class ALLOCATOR> static void destructiveMoveAndMoveInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer *lastPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, typename bsl::allocator_traits<ALLOCATOR>::pointer first, typename bsl::allocator_traits<ALLOCATOR>::pointer last, size_type numElements, ALLOCATOR allocator); // TBD: improve comment // Move, into an uninitialized array beginning at the specified // 'toBegin' pointer, elements of type given by the 'allocator_traits' // class template for (template parameter) 'ALLOCATOR', from elements // starting at the specified 'fromBegin' pointer and ending immediately // before the specified 'fromEnd' address, moving into the specified // 'position' (after translating from 'fromBegin' to 'toBegin') the // specified 'numElements' elements starting at the specified 'first' // pointer and ending immediately before the specified 'last' pointer. // Keep the pointer at the specified 'fromEndPtr' address pointing to // the first uninitialized element in '[ fromBegin, fromEnd)' as the // elements are moved from source to destination. The behavior is // undefined unless 'fromBegin <= position <= fromEnd' and the // destination array contains at least // '(fromEnd - fromBegin) + numElements' uninitialized elements. If a // constructor or assignment operator for the target type throws an // exception, then any elements created in the output array are // destroyed and the elements in the range '[ fromBegin, *fromEndPtr )' // will have valid but unspecified values. template <class TARGET_TYPE> static void destructiveMoveAndMoveInsert(TARGET_TYPE *toBegin, TARGET_TYPE **fromEndPtr, TARGET_TYPE **lastPtr, TARGET_TYPE *fromBegin, TARGET_TYPE *position, TARGET_TYPE *fromEnd, TARGET_TYPE *first, TARGET_TYPE *last, size_type numElements, bslma::Allocator *allocator); // Move the elements of (template parameter) 'TARGET_TYPE' in the array // starting at the specified 'fromBegin' address and ending immediately // before the specified 'fromEnd' address into an uninitialized array // of 'TARGET_TYPE' at the specified 'toBegin' address, moving into the // specified 'position' (after translating from 'fromBegin' to // 'toBegin') the specified 'numElements' of the 'TARGET_TYPE' from the // array starting at the specified 'first' address and ending // immediately before the specified 'last' address. Keep the pointer // at the specified 'fromEndPtr' address pointing to the first // uninitialized element in '[fromBegin, fromEnd)', and the pointer at // the specified 'lastPtr' address pointing to the end of the moved // range as the elements from the range '[ first, last)' are moved from // source to destination. The behavior is undefined unless // 'fromBegin <= position <= fromEnd', the destination array contains // at least '(fromEnd - fromBegin) + numElements' uninitialized // elements after 'toBegin', and 'numElements' is the distance from // 'first' to 'last'. If a copy constructor or assignment operator for // 'TARGET_TYPE' throws an exception, then any elements in // '[ *lastPtr, last )' as well as in '[ toBegin, ... )' are destroyed, // and the elements in the ranges '[ first, *lastPtr )' and // '[ fromBegin, *fromEndPtr )' will have unspecified but valid values. #if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES // {{{ BEGIN GENERATED CODE // Command line: sim_cpp11_features.pl bslalg_arrayprimitives.h #ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT #define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT 10 #endif #ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B #define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT #endif #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 0 template <class ALLOCATOR> static void emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 0 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 1 template <class ALLOCATOR, class ARGS_01> static void emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 1 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 2 template <class ALLOCATOR, class ARGS_01, class ARGS_02> static void emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 2 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 3 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03> static void emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 3 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 4 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04> static void emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 4 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 5 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05> static void emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 5 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 6 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06> static void emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 6 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 7 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07> static void emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 7 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 8 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08> static void emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 8 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 9 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09> static void emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 9 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 10 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09, class ARGS_10> static void emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 10 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 0 template <class TARGET_TYPE> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *allocator); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 0 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 1 template <class TARGET_TYPE, class ARGS_01> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 1 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 2 template <class TARGET_TYPE, class ARGS_01, class ARGS_02> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 2 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 3 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 3 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 4 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 4 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 5 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 5 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 6 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 6 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 7 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 7 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 8 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 8 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 9 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 9 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 10 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09, class ARGS_10> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_B >= 10 #else // The generated code below is a workaround for the absence of perfect // forwarding in some compilers. template <class ALLOCATOR, class... ARGS> static void emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments); template <class TARGET_TYPE, class... ARGS> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args); // }}} END GENERATED CODE #endif #if defined(BSLS_PLATFORM_CMP_MSVC) && BSLS_PLATFORM_CMP_VERSION < 1900 template <class CLASS_TYPE, class MEMBER_TYPE, class... ARGS> static void emplace(MEMBER_TYPE CLASS_TYPE::* *toBegin, MEMBER_TYPE CLASS_TYPE::* *toEnd, bslma::Allocator *allocator) // Old Microsoft compilers need help value-initializing elements that // are pointer-to-member types. { emplace(toBegin, toEnd, allocator, nullptr); } #endif template <class ALLOCATOR> static void erase(typename bsl::allocator_traits<ALLOCATOR>::pointer first, typename bsl::allocator_traits<ALLOCATOR>::pointer middle, typename bsl::allocator_traits<ALLOCATOR>::pointer last, ALLOCATOR allocator); // TBD: improve comment // Destroy the elements of type given by the 'allocator_traits' class // template for (template parameter) 'ALLOCATOR' starting at the // specified 'first' 'first' pointer and ending immediately before the // specified 'middle' pointer, and move the elements in the array // starting at 'middle' and ending at the specified 'last' pointer down // to the 'first' pointer. If an assignment throws an exception during // this process, all of the elements in the range '[ first, last )' // will have unspecified but valid values, and no elements are // destroyed. The behavior is undefined unless // 'first <= middle <= last'. template <class TARGET_TYPE> static void erase(TARGET_TYPE *first, TARGET_TYPE *middle, TARGET_TYPE *last, bslma::Allocator *allocator = 0); // Destroy the elements of the parameterized 'TARGET_TYPE' in the array // starting at the specified 'first' address and ending immediately // before the specified 'middle' address, and move the elements in the // array starting at 'middle' and ending at the specified 'last' // address down to the 'first' address. If an assignment throws an // exception during this process, all of the elements in the range // '[ first, last )' will have unspecified but valid values, and no // elements are destroyed. The behavior is undefined unless // 'first <= middle <= last'. template <class ALLOCATOR> static void insert(typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, bslmf::MovableRef< typename bsl::allocator_traits<ALLOCATOR>::value_type> value, ALLOCATOR allocator); // Insert the specified 'value' into the array of // 'allocator_traits<ALLOCATOR>::value_type' objects at the specified // 'toBegin' location, shifting forward the elements from 'toBegin' to // the specified 'toEnd' location by one position. 'value' is left in // a valid but unspecified state. If a (copy or move) constructor or a // (copy or move) assignment operator throws an exception, then any // elements created after 'toEnd' are destroyed and the elements in the // range '[toBegin .. toEnd )' are left in a valid but unspecified // state. The behavior is undefined unless 'toBegin' refers to // sufficient space to hold at least 'toEnd - toBegin + 1' elements. template <class TARGET_TYPE> static void insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslmf::MovableRef<TARGET_TYPE> value, bslma::Allocator *allocator); // Insert the specified 'value' into the array of the (template // parameter) type 'TARGET_TYPE' at the specified 'toBegin' address, // shifting the elements from 'toBegin' to the specified 'toEnd' // address by one position towards larger addresses. 'value' is left // in a valid but unspecified state. If a (copy or move) constructor // or a (copy or move) assignment operator throws an exception, then // any elements created after 'toEnd' are destroyed and the elements in // the range '[toBegin .. toEnd )' are left in a valid but unspecified // state. The behavior is undefined unless 'toBegin' refers to // sufficient space to hold at least 'toEnd - toBegin + 1' elements. template <class ALLOCATOR> static void insert( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, const typename bsl::allocator_traits<ALLOCATOR>::value_type& value, size_type numElements, ALLOCATOR allocator); // Insert the specified 'numElements' copies of the specified 'value' // into the array of type 'allocator_traits<ALLOCATOR>::value_type' // starting at the specified 'toBegin' location, shifting forward the // elements from 'toBegin' to the specified 'toEnd' location by // 'numElements' positions. If a (copy or move) constructor or a (copy // or move) assignment operator throws an exception, any elements // created after 'toEnd' are destroyed and the elements in the range // '[toBegin .. toEnd)' are left in a valid but unspecified state. The // behavior is undefined unless 'toBegin' refers to space sufficient to // hold at least 'toEnd - toBegin + numElements' elements. template <class TARGET_TYPE> static void insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, const TARGET_TYPE& value, size_type numElements, bslma::Allocator *allocator); // Insert the specified 'numElements' copies of the specified 'value' // into the array of (template parameter) 'TARGET_TYPE' starting at the // specified 'toBegin' address and ending immediately before the // specified 'toEnd' address, shifting the elements in the array by // 'numElements' positions towards larger addresses. The behavior is // undefined unless the destination array contains at least // 'numElements' uninitialized elements after 'toEnd'. If a copy // constructor or assignment operator for 'TARGET_TYPE' throws an // exception, then any elements created after 'toEnd' are destroyed and // the elements in the range '[ toBegin, toEnd )' will have // unspecified, but valid, values. template <class ALLOCATOR, class FWD_ITER> static void insert(typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, FWD_ITER fromBegin, FWD_ITER fromEnd, size_type numElements, ALLOCATOR allocator); template <class ALLOCATOR, class SOURCE_TYPE> static void insert(typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, SOURCE_TYPE *fromBegin, SOURCE_TYPE *fromEnd, size_type numElements, ALLOCATOR allocator); // TBD: improve comment // Insert the specified 'numElements' from the range starting at the // specified 'fromBegin' and ending immediately before the specified // 'fromEnd' iterators of (template parameter) 'FWD_ITER' type (or // template parameter 'SOURCE_TYPE *'), into the array of elements of // type given by the 'allocator_traits' class template for (template // parameter) 'ALLOCATOR', starting at the specified 'toBegin' address, // shifting forward the elements in the array by 'numElements' // positions. The behavior is undefined unless the destination array // contains 'numElements' uninitialized elements after 'toEnd', // 'numElements' is the distance between 'fromBegin' and 'fromEnd', // and the input array and the destination array do not overlap. If a // copy constructor or assignment operator throws an exception, then // any elements created after 'toEnd' are destroyed and the elements in // the range '[ toBegin, toEnd )' will have valid but unspecified // values. template <class TARGET_TYPE, class FWD_ITER> static void insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, FWD_ITER fromBegin, FWD_ITER fromEnd, size_type numElements, bslma::Allocator *allocator); template <class TARGET_TYPE, class SOURCE_TYPE> static void insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, SOURCE_TYPE *fromBegin, SOURCE_TYPE *fromEnd, size_type numElements, bslma::Allocator *allocator); // Insert, into the array at the specified 'toBegin' location, the // specified 'numElements' from the range starting at the specified // 'fromBegin' and ending immediately before the specified 'fromEnd' // iterators of the (template parameter) 'FWD_ITER' type (or the // (template parameter) 'SOURCE_TYPE *'), into the array of elements of // the parameterized 'TARGET_TYPE' starting at the specified 'toBegin' // address and ending immediately before the specified 'toEnd' address, // shifting the elements in the array by 'numElements' positions // towards larger addresses. The behavior is undefined unless the // destination array contains 'numElements' uninitialized elements // after 'toEnd', 'numElements' is the distance between 'fromBegin' and // 'fromEnd', and the input array and the destination array do not // overlap. If a copy constructor or assignment operator for // 'TARGET_TYPE' throws an exception, then any elements created after // 'toEnd' are destroyed and the elements in the range // '[ toBegin, toEnd )' will have unspecified, but valid, values. template <class ALLOCATOR> static void moveInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, size_type numElements, ALLOCATOR allocator); // TBD: improve comment // Move the elements of type given by the 'allocator_traits' class // template for (template parameter) 'ALLOCATOR' in the array starting // at the specified 'toBegin' location and ending immediately before // the specified 'toEnd' location by the specified 'numElements' // positions towards larger addresses, and fill the 'numElements' at // the 'toBegin' location by moving the elements from the array // starting at the specified 'fromBegin' and ending immediately before // the specified 'fromEnd' location. Keep the iterator at the // specified 'fromEndPtr' address pointing to the end of the range as // the elements from '[ fromBegin, fromEnd )' are moved from source to // destination. The behavior is undefined unless the destination array // contains 'numElements' uninitialized elements after 'toEnd', // 'numElements' is the distance from 'fromBegin' to 'fromEnd', and the // input and destination arrays do not overlap. If a copy constructor // or assignment operator for 'TARGET_TYPE' throws an exception, then // any elements created after 'toEnd' are destroyed, the elements in // the ranges '[ toBegin, toEnd)' and '[ fromBegin, *fromEndPtr )' will // have unspecified, but valid, values, and the elements in // '[ *fromEndPtr, fromEnd )' will be destroyed. template <class TARGET_TYPE> static void moveInsert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, TARGET_TYPE **fromEndPtr, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, size_type numElements, bslma::Allocator *allocator); // Move the elements of the (template parameter) 'TARGET_TYPE' in the // array starting at the specified 'toBegin' address and ending // immediately before the specified 'toEnd' address by the specified // 'numElements' positions towards larger addresses, and fill the // 'numElements' at the 'toBegin' address by moving the elements from // the array starting at the specified 'fromBegin' and ending // immediately before the specified 'fromEnd' address. Keep the // iterator at the specified 'fromEndPtr' address pointing to the end // of the range as the elements from '[ fromBegin, fromEnd )' are moved // from source to destination. The behavior is undefined unless the // destination array contains 'numElements' uninitialized elements // after 'toEnd', 'numElements' is the distance from 'fromBegin' to // 'fromEnd', and the input and destination arrays do not overlap. If // a copy constructor or assignment operator for 'TARGET_TYPE' throws // an exception, then any elements created after 'toEnd' are destroyed, // the elements in the ranges '[ toBegin, toEnd)' and // '[ fromBegin, *fromEndPtr )' will have unspecified, but valid, // values, and the elements in '[ *fromEndPtr, fromEnd )' will be // destroyed. template <class TARGET_TYPE> static void rotate(TARGET_TYPE *first, TARGET_TYPE *middle, TARGET_TYPE *last); // Move the elements of the parameterized 'TARGET_TYPE' in the array // starting at the specified 'first' address and ending immediately // before the specified 'middle' address to the array of the same // length ending at the specified 'last' address (and thus starting at // the 'last - (middle - first)' address), and move the elements // previously in the array starting at 'middle' and ending at 'last' // down to the 'first' address. If the assignment operator throws an // exception during this process, all of the elements in // '[ first, last )' will have unspecified, but valid, values. The // behavior is undefined unless 'first <= middle <= last'. template <class ALLOCATOR> static void uninitializedFillN( typename bsl::allocator_traits<ALLOCATOR>::pointer begin, size_type numElements, const typename bsl::allocator_traits<ALLOCATOR>::value_type& value, ALLOCATOR allocator); // TBD: improve comment // Construct copies of the specified 'value' of type given by the // 'allocator_traits' class template for (template parameter) // 'ALLOCATOR' into the uninitialized array containing the specified // 'numElements' starting at the specified 'begin' location. The // behavior is undefined unless the output array contains at least // 'numElements' uninitialized elements after 'begin'. If a // constructor throws an exception during the operation, then the // destructor is called on any newly-constructed elements, leaving the // output array in an uninitialized state. template <class TARGET_TYPE> static void uninitializedFillN(TARGET_TYPE *begin, size_type numElements, const TARGET_TYPE& value, bslma::Allocator *allocator); // Construct copies of the specified 'value' of the parameterized type // 'TARGET_TYPE' into the uninitialized array containing the specified // 'numElements' starting at the specified 'begin' address. If the // (template parameter) 'ALLOCATOR' type is derived from // 'bslma::Allocator' and 'TARGET_TYPE' supports 'bslma' allocators, // then the specified 'allocator' is passed to each invocation of the // 'TARGET_TYPE' copy constructor. The behavior is undefined unless // the output array contains at least 'numElements' uninitialized // elements after 'begin'. If a 'TARGET_TYPE' constructor throws an // exception during the operation, then the destructor is called on any // newly-constructed elements, leaving the output array in an // uninitialized state. Note that the argument order was chosen to // maintain compatibility with the existing 'bslalg'. }; // ========================== // struct ArrayPrimitives_Imp // ========================== struct ArrayPrimitives_Imp { // This 'struct' provides a namespace for a suite of independent utility // functions that operate on arrays of elements of a parameterized // 'TARGET_TYPE'. These utility functions are only for the purpose of // implementing those in the 'ArrayPrimitives' utility. For brevity, we do // not repeat the main contracts here, but instead refer to the // corresponding contract in the 'ArrayPrimitives' utility. private: // PRIVATE METHODS template <class TARGET_TYPE> static void assign(TARGET_TYPE *srcStart, TARGET_TYPE *srcEnd, TARGET_TYPE& value); // Copy-assign the specified 'value' to the range starting at the // specified 'srcStart' and ending immediately before the specified // 'srcEnd'. Note that the (template parameter) 'TARGET_TYPE' must be // copy-assignable. Also note that 'value' should not be an element in // the range '[srcStart, srcEnd)'. template <class TARGET_TYPE> static void reverseAssign(TARGET_TYPE *dest, TARGET_TYPE *srcStart, TARGET_TYPE *srcEnd); // Copy-assign the elements in reverse order from the range starting at // the specified 'srcStart' and ending immediately before the specified // 'srcEnd' to the range starting at the specified 'dest' and ending // immediately before 'dest + (srcEnd - srcStart)'. The behavior is // undefined unless each element is both range '[srcStart, srcEnd)' and // range '[dest, dest + (srcEnd - srcStart))' is valid. Note that the // (template parameter) 'TARGET_TYPE' must be copy-assignable. Also // note that this method is intended to support range assignment when // the two ranges may be overlapped, and 'srcStart <= dest'. public: // TYPES typedef ArrayPrimitives::size_type size_type; typedef ArrayPrimitives::difference_type difference_type; enum { // These constants are used in the overloads below, when the last // argument is of type 'bslmf::MetaInt<N> *', indicating that // 'TARGET_TYPE' has the traits for which the enumerator equal to 'N' // is named. e_IS_ITERATOR_TO_FUNCTION_POINTER = 6, e_IS_POINTER_TO_POINTER = 5, e_IS_FUNDAMENTAL_OR_POINTER = 4, e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS = 3, e_BITWISE_COPYABLE_TRAITS = 2, e_BITWISE_MOVEABLE_TRAITS = 1, e_NIL_TRAITS = 0 }; enum { // Number of bytes for which a stack-allocated buffer can be // comfortably obtained to optimize bitwise moves. k_INPLACE_BUFFER_SIZE = 16 * bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT }; // CLASS METHODS static void bitwiseFillN(char *begin, size_type numBytesInitialized, size_type numBytes); // Fill the specified 'numBytes' in the array starting at the specified // 'begin' address, as if by bit-wise copying the specified // 'numBytesInitialized' at every offset that is a multiple of // 'numBytesInitialized' within the output array. The behavior is // undefined unless 'numBytesInitialized <= numBytes'. Note that // 'numBytes' usually is, but does not have to be, a multiple of // 'numBytesInitialized'. static void uninitializedFillN( bool *begin, bool value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( char *begin, char value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( unsigned char *begin, unsigned char value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( signed char *begin, signed char value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( wchar_t *begin, wchar_t value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( short *begin, short value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( unsigned short *begin, unsigned short value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( int *begin, int value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( unsigned int *begin, unsigned int value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( long *begin, long value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( unsigned long *begin, unsigned long value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( bsls::Types::Int64 *begin, bsls::Types::Int64 value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( bsls::Types::Uint64 *begin, bsls::Types::Uint64 value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( float *begin, float value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( double *begin, double value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( long double *begin, long double value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( void **begin, void *value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( const void **begin, const void *value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( volatile void **begin, volatile void *value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); static void uninitializedFillN( const volatile void **begin, const volatile void *value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); template <class TARGET_TYPE> static void uninitializedFillN( TARGET_TYPE **begin, TARGET_TYPE *value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); template <class TARGET_TYPE> static void uninitializedFillN( const TARGET_TYPE **begin, const TARGET_TYPE *value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); template <class TARGET_TYPE> static void uninitializedFillN( volatile TARGET_TYPE **begin, volatile TARGET_TYPE *value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); template <class TARGET_TYPE> static void uninitializedFillN( const volatile TARGET_TYPE **begin, const volatile TARGET_TYPE *value, size_type numElements, void * = 0, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> * = 0); template <class TARGET_TYPE, class ALLOCATOR> static void uninitializedFillN( TARGET_TYPE *begin, const TARGET_TYPE& value, size_type numElements, ALLOCATOR *allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *); template <class TARGET_TYPE, class ALLOCATOR> static void uninitializedFillN(TARGET_TYPE *begin, const TARGET_TYPE& value, size_type numElements, ALLOCATOR *allocator, bslmf::MetaInt<e_NIL_TRAITS> *); // Copy the specified 'value' of the parameterized 'TARGET_TYPE' into // every of the specified 'numElements' in the array starting at the // specified 'begin' address. Pass the specified 'allocator' to the // copy constructor if appropriate. Note that if 'TARGET_TYPE' is // bit-wise copyable or is not based on 'bslma::Allocator', 'allocator' // is ignored. The last argument is for removing overload ambiguities // and is not used. template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR> static void copyConstruct(TARGET_TYPE *toBegin, FWD_ITER fromBegin, FWD_ITER fromEnd, ALLOCATOR allocator, bslmf::MetaInt<e_IS_POINTER_TO_POINTER> *); template <class TARGET_TYPE, class ALLOCATOR> static void copyConstruct( TARGET_TYPE *toBegin, const TARGET_TYPE *fromBegin, const TARGET_TYPE *fromEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *); template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR> static void copyConstruct(TARGET_TYPE *toBegin, FWD_ITER fromBegin, FWD_ITER fromEnd, ALLOCATOR allocator, bslmf::MetaInt<e_IS_ITERATOR_TO_FUNCTION_POINTER> *); template <class FWD_ITER, class ALLOCATOR> static void copyConstruct(void **toBegin, FWD_ITER fromBegin, FWD_ITER fromEnd, ALLOCATOR allocator, bslmf::MetaInt<e_IS_ITERATOR_TO_FUNCTION_POINTER> *); template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR> static void copyConstruct(TARGET_TYPE *toBegin, FWD_ITER fromBegin, FWD_ITER fromEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *); // These functions follow the 'copyConstruct' contract. If the // (template parameter) 'ALLOCATOR' type is based on 'bslma::Allocator' // and the 'TARGET_TYPE' constructors take an allocator argument, then // pass the specified 'allocator' to the copy constructor. The // behavior is undefined unless the output array has length at least // the distance from the specified 'fromBegin' to the specified // 'fromEnd'. Note that if 'FWD_ITER' is the 'TARGET_TYPE *' pointer // type and 'TARGET_TYPE' is bit-wise copyable, then this operation is // simply 'memcpy'. The last argument is for removing overload // ambiguities and is not used. template <class TARGET_TYPE, class ALLOCATOR> static void moveConstruct( TARGET_TYPE *toBegin, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *); template <class TARGET_TYPE, class ALLOCATOR> static void moveConstruct( TARGET_TYPE *toBegin, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *); // TBD: improve comment // Move-insert into an uninitialized array beginning at the specified // 'toBegin' pointer, elements of type given by the 'allocator_traits' // class template for (template parameter) 'ALLOCATOR' from elements // starting at the specified 'fromBegin' pointer and ending immediately // before the specified 'fromEnd' pointer. The elements in the range // '[fromBegin...fromEnd)' are left in a valid but unspecified state. // If a constructor throws an exception during the operation, then the // destructor is called on any newly-constructed elements, leaving the // output array in an uninitialized state. The behavior is undefined // unless 'toBegin' refers to space sufficient to hold // 'fromEnd - fromBegin' elements. template <class TARGET_TYPE, class ALLOCATOR> static void moveIfNoexcept( TARGET_TYPE *toBegin, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *); // TBD: improve comment // Either move- or copy-insert into an uninitialized array beginning at // the specified 'toBegin' pointer, elements of type given by the // 'allocator_traits' class template for (template parameter) // 'ALLOCATOR' from elements starting at the specified 'fromBegin' // pointer and ending immediately before the specified 'fromEnd' // pointer. The elements in the range '[fromBegin...fromEnd)' are left // in a valid but unspecified state. Use the move constructor if it is // guaranteed to not throw or if the target type does not define a copy // constructor; otherwise use the copy constructor. If a constructor // throws an exception during the operation, then the destructor is // called on any newly-constructed elements, leaving the output array // in an uninitialized state. The behavior is undefined unless // 'toBegin' refers to space sufficient to hold 'fromEnd - fromBegin' // elements. template <class TARGET_TYPE, class ALLOCATOR> static void defaultConstruct( TARGET_TYPE *begin, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS> *); template <class TARGET_TYPE, class ALLOCATOR> static void defaultConstruct( TARGET_TYPE *begin, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *); template <class TARGET_TYPE, class ALLOCATOR> static void defaultConstruct(TARGET_TYPE *begin, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *); // Use the default constructor of the (template parameter) // 'TARGET_TYPE' (or 'memset' to 0 if 'TARGET_TYPE' has a trivial // default constructor) on each element of the array starting at the // specified 'begin' address and ending immediately before the 'end' // address. Pass the specified 'allocator' to the default constructor // if appropriate. The last argument is for traits overloading // resolution only and its value is ignored. template <class TARGET_TYPE, class ALLOCATOR> static void destructiveMove( TARGET_TYPE *toBegin, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *); template <class TARGET_TYPE, class ALLOCATOR> static void destructiveMove(TARGET_TYPE *toBegin, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *); // These functions follow the 'destructiveMove' contract. Note that // both arrays cannot overlap (one contains only initialized elements // and the other only uninitialized elements), and that if // 'TARGET_TYPE' is bit-wise moveable, then this operation is simply // 'memcpy'. The last argument is for removing overload ambiguities // and is not used. #if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES // {{{ BEGIN GENERATED CODE // Command line: sim_cpp11_features.pl bslalg_arrayprimitives.h #ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT #define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT 10 #endif #ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C #define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT #endif #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 0 template <class TARGET_TYPE, class ALLOCATOR> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 0 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 1 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 1 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 2 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 2 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 3 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 3 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 4 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 4 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 5 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 5 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 6 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 6 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 7 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 7 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 8 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 8 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 9 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 9 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 10 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09, class ARGS_10> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 10 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 0 template <class TARGET_TYPE, class ALLOCATOR> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 0 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 1 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 1 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 2 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 2 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 3 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 3 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 4 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 4 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 5 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 5 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 6 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 6 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 7 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 7 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 8 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 8 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 9 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 9 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 10 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09, class ARGS_10> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 10 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 0 template <class TARGET_TYPE, class ALLOCATOR> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 0 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 1 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 1 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 2 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 2 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 3 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 3 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 4 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 4 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 5 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 5 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 6 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 6 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 7 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 7 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 8 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 8 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 9 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 9 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 10 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09, class ARGS_10> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10); #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_C >= 10 #else // The generated code below is a workaround for the absence of perfect // forwarding in some compilers. template <class TARGET_TYPE, class ALLOCATOR, class... ARGS> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args); template <class TARGET_TYPE, class ALLOCATOR, class... ARGS> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args); template <class TARGET_TYPE, class ALLOCATOR, class... ARGS> static void emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args); // }}} END GENERATED CODE #endif template <class TARGET_TYPE, class ALLOCATOR> static void erase(TARGET_TYPE *first, TARGET_TYPE *middle, TARGET_TYPE *last, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *); template <class TARGET_TYPE, class ALLOCATOR> static void erase(TARGET_TYPE *first, TARGET_TYPE *middle, TARGET_TYPE *last, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *); // These functions follow the 'erase' contract. Note that if (template // parameter) 'TARGET_TYPE' is bit-wise moveable, then this operation // can be implemented by first bit-wise moving the elements in // '[middle, last)' towards first, and destroying // '[ last - (middle - first), last)'; note that this cannot throw // exceptions. template <class TARGET_TYPE, class ALLOCATOR> static void insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, const TARGET_TYPE& value, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *); template <class TARGET_TYPE, class ALLOCATOR> static void insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, const TARGET_TYPE& value, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *); template <class TARGET_TYPE, class ALLOCATOR> static void insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, const TARGET_TYPE& value, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *); // These functions follow the 'insert' contract. Note that if // 'TARGET_TYPE' is bit-wise copyable, then this operation is simply // 'memmove' followed by 'bitwiseFillN'. If 'TARGET_TYPE' is bit-wise // moveable, then this operation can still be optimized using 'memmove' // followed by repeated assignments, but a guard needs to be set up. // The last argument is for removing overload ambiguities and is not // used. template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR> static void insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, FWD_ITER fromBegin, FWD_ITER fromEnd, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_IS_POINTER_TO_POINTER> *); template <class TARGET_TYPE, class ALLOCATOR> static void insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, const TARGET_TYPE *fromBegin, const TARGET_TYPE *fromEnd, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *); template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR> static void insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, FWD_ITER fromBegin, FWD_ITER fromEnd, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *); template <class FWD_ITER, class ALLOCATOR> static void insert(void **toBegin, void **toEnd, FWD_ITER fromBegin, FWD_ITER fromEnd, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_IS_ITERATOR_TO_FUNCTION_POINTER> *); template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR> static void insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, FWD_ITER fromBegin, FWD_ITER fromEnd, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *); // These functions follow the 'insert' contract. Note that if // 'TARGET_TYPE' is bit-wise copyable and 'FWD_ITER' is convertible to // 'const TARGET_TYPE *', then this operation is simply 'memmove' // followed by 'memcpy'. If 'TARGET_TYPE' is bit-wise moveable and // 'FWD_ITER' is convertible to 'const TARGET_TYPE *', then this // operation can still be optimized using 'memmove' followed by // repeated copies. The last argument is for removing overload // ambiguities and is not used. template <class TARGET_TYPE, class ALLOCATOR> static void moveInsert( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, TARGET_TYPE **lastPtr, TARGET_TYPE *first, TARGET_TYPE *last, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *); template <class TARGET_TYPE, class ALLOCATOR> static void moveInsert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, TARGET_TYPE **lastPtr, TARGET_TYPE *first, TARGET_TYPE *last, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *); // These functions follow the 'moveInsert' contract. Note that if // 'TARGET_TYPE' is at least bit-wise moveable, then this operation is // simply 'memmove' followed by 'memcpy'. template <class TARGET_TYPE> static void rotate(TARGET_TYPE *begin, TARGET_TYPE *middle, TARGET_TYPE *end, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *); template <class TARGET_TYPE> static void rotate(TARGET_TYPE *begin, TARGET_TYPE *middle, TARGET_TYPE *end, bslmf::MetaInt<e_NIL_TRAITS> *); // These functions follow the 'rotate' contract, but the first overload // is optimized when the parameterized 'TARGET_TYPE' is bit-wise // moveable. The last argument is for removing overload ambiguities // and is not used. Note that if 'TARGET_TYPE' is bit-wise moveable, // the 'rotate(char*, char*, char*)' can be used, enabling to take the // whole implementation out-of-line. template <class ALLOCATOR> static void shiftAndInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer begin, typename bsl::allocator_traits<ALLOCATOR>::pointer end, bslmf::MovableRef< typename bsl::allocator_traits<ALLOCATOR>::value_type> value, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *); template <class ALLOCATOR> static void shiftAndInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer begin, typename bsl::allocator_traits<ALLOCATOR>::pointer end, bslmf::MovableRef< typename bsl::allocator_traits<ALLOCATOR>::value_type> value, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *); template <class ALLOCATOR> static void shiftAndInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer begin, typename bsl::allocator_traits<ALLOCATOR>::pointer end, bslmf::MovableRef< typename bsl::allocator_traits<ALLOCATOR>::value_type> value, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *); // Shift the specified '[begin, end)' sequence one position right, then // insert the specified 'value' at the position pointed by 'begin'. // The specified 'allocator' is used for the element construction. The // behavior is undefined unless the specified '[begin, end)' sequence // contains at least one element. // 'bitwise' METHODS static void bitwiseRotate(char *begin, char *middle, char *end); // This function follows the 'rotate' contract, but by using bit-wise // moves on the underlying 'char' array. static void bitwiseRotateBackward(char *begin, char *middle, char *end); // Move the characters in the array starting at the specified 'first' // address and ending immediately before the specified 'middle' address // to the array of the same length ending at the specified 'last' // address (and thus starting at the 'last - (middle - first)' // address), and move the elements previously in the array starting at // 'middle' and ending at 'last' down to the 'first' address. The // behavior is undefined unless // 'middle - begin <= k_INPLACE_BUFFER_SIZE'. static void bitwiseRotateForward(char *begin, char *middle, char *end); // Move the characters in the array starting at the specified 'first' // address and ending immediately before the specified 'middle' address // to the array of the same length ending at the specified 'last' // address (and thus starting at the 'last - (middle - first)' // address), and move the elements previously in the array starting at // 'middle' and ending at 'last' down to the 'first' address. The // behavior is undefined unless // 'end - middle <= k_INPLACE_BUFFER_SIZE'. static void bitwiseSwapRanges(char *begin, char *middle, char *end); // Swap the characters in the array starting at the specified 'first' // address and ending immediately before the specified 'middle' address // with the array of the same length starting at the 'middle' address // and ending at the specified 'last' address. The behavior is // undefined unless 'middle - begin == end - middle'. template <class FORWARD_ITERATOR> static bool isInvalidRange(FORWARD_ITERATOR begin, FORWARD_ITERATOR end); template <class TARGET_TYPE> static bool isInvalidRange(TARGET_TYPE *begin, TARGET_TYPE *end); // Return 'true' if the specified 'begin' and the specified 'end' // provably do not form a valid semi-open range, '[begin, end)', and // 'false' otherwise. Note that 'begin == null == end' produces a // valid range, and any other use of the null pointer value will return // 'true'. Also note that this function is intended to support // testing, primarily through assertions, so will return 'false' unless // it can *prove* that the passed range is invalid. Currently, this // function can prove invalid ranges only for pointers, although should // also encompass generic random access iterators in a future update, // where iterator tag types are levelized below 'bslalg'. }; // ============================================================================ // INLINE FUNCTION DEFINITIONS // ============================================================================ // IMPLEMENTATION NOTES: Specializations of 'uninitializedFillN' for most // fundamental types are not templates nor inline, and thus can be found in the // '.cpp' file. // ===================================== // struct ArrayPrimitives_CanBitwiseCopy // ===================================== template <class FROM_TYPE, class TO_TYPE> struct ArrayPrimitives_CanBitwiseCopy : bsl::integral_constant<bool, bsl::is_same< typename bsl::remove_const<FROM_TYPE>::type, typename bsl::remove_const<TO_TYPE >::type> ::value && bsl::is_trivially_copyable< typename bsl::remove_const<TO_TYPE >::type> ::value > { }; // ---------------------- // struct ArrayPrimitives // ---------------------- template <class ALLOCATOR> inline void ArrayPrimitives::uninitializedFillN( typename bsl::allocator_traits<ALLOCATOR>::pointer begin, size_type numElements, const typename bsl::allocator_traits<ALLOCATOR>::value_type& value, ALLOCATOR allocator) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { // We provide specialized overloads of 'uninitializedFillN' for // fundamental and pointer types. However, function pointers can have // extern "C" linkage and SunPro doesn't match them properly with the // pointer template function overload in 'Imp', so we resort to the // general case for those. k_IS_FUNCTION_POINTER = bslmf::IsFunctionPointer<TargetType>::value, k_IS_FUNDAMENTAL = bsl::is_fundamental<TargetType>::value, k_IS_POINTER = bsl::is_pointer<TargetType>::value, k_IS_FUNDAMENTAL_OR_POINTER = k_IS_FUNDAMENTAL || (k_IS_POINTER && !k_IS_FUNCTION_POINTER), k_IS_BITWISECOPYABLE = bsl::is_trivially_copyable<TargetType>::value, k_VALUE = k_IS_FUNDAMENTAL_OR_POINTER ? Imp::e_IS_FUNDAMENTAL_OR_POINTER : k_IS_BITWISECOPYABLE ? Imp::e_BITWISE_COPYABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::uninitializedFillN(begin, value, numElements, &allocator, (bslmf::MetaInt<k_VALUE>*)0); } template <class TARGET_TYPE> inline void ArrayPrimitives::uninitializedFillN(TARGET_TYPE *begin, size_type numElements, const TARGET_TYPE& value, bslma::Allocator *basicAllocator) { uninitializedFillN<bsl::allocator<TARGET_TYPE> >(begin, numElements, value, basicAllocator); } template <class ALLOCATOR, class FWD_ITER> void ArrayPrimitives::copyConstruct( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, FWD_ITER fromBegin, FWD_ITER fromEnd, ALLOCATOR allocator) { BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd); BSLMF_ASSERT(!bsl::is_pointer<FWD_ITER>::value); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; typedef typename FWD_ITER::value_type FwdTarget; // Overload resolution will handle the case where 'FWD_ITER' is a raw // pointer, so we need handle only user-defined iterators. As 'bslalg' // is levelized below 'bslstl' we cannot use 'iterator_traits', but // rely on the same property as 'iterator_traits' that this typedef // must be defined for any standard-conforming iterator, unless the // iterator explicitly specialized the 'std::iterator_traits' template. // In practice, iterators always prefer to provide the member typedef // than specialize the traits as it is a much simpler implementation, // so this assumption is good enough. // // Also note that as we know that 'FWD_ITER' is not a pointer, then we // cannot take advantage of bitwise copying as we do not have pointers // to pass to the 'memcpy' describing the whole range. It is not worth // the effort to try to bitwise copy one element at a time. typedef typename bsl::remove_pointer<TargetType>::type RemovePtrTarget; // We want to detect the special case of copying function pointers to // 'void *' or 'const void *' pointers. enum { k_ITER_TO_FUNC_PTRS = bslmf::IsFunctionPointer<FwdTarget>::value, k_TARGET_IS_VOID_PTR = bsl::is_pointer<TargetType>::value && bsl::is_void<RemovePtrTarget>::value, k_VALUE = k_ITER_TO_FUNC_PTRS && k_TARGET_IS_VOID_PTR ? Imp::e_IS_ITERATOR_TO_FUNCTION_POINTER : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::copyConstruct(toBegin, fromBegin, fromEnd, allocator, (bslmf::MetaInt<k_VALUE>*)0); } template <class TARGET_TYPE, class FWD_ITER> inline void ArrayPrimitives::copyConstruct(TARGET_TYPE *toBegin, FWD_ITER fromBegin, FWD_ITER fromEnd, bslma::Allocator *basicAllocator) { copyConstruct<bsl::allocator<TARGET_TYPE> >(toBegin, fromBegin, fromEnd, basicAllocator); } template <class ALLOCATOR, class SOURCE_TYPE> inline void ArrayPrimitives::copyConstruct( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, SOURCE_TYPE *fromBegin, SOURCE_TYPE *fromEnd, ALLOCATOR allocator) { BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_ARE_PTRS_TO_PTRS = bsl::is_pointer<TargetType>::value && bsl::is_pointer<SOURCE_TYPE>::value, k_IS_BITWISECOPYABLE = ArrayPrimitives_CanBitwiseCopy<SOURCE_TYPE, TargetType>::value, k_VALUE = k_ARE_PTRS_TO_PTRS ? Imp::e_IS_POINTER_TO_POINTER : k_IS_BITWISECOPYABLE ? Imp::e_BITWISE_COPYABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::copyConstruct(toBegin, fromBegin, fromEnd, allocator, (bslmf::MetaInt<k_VALUE>*)0); } template <class TARGET_TYPE, class SOURCE_TYPE> inline void ArrayPrimitives::copyConstruct(TARGET_TYPE *toBegin, SOURCE_TYPE *fromBegin, SOURCE_TYPE *fromEnd, bslma::Allocator *basicAllocator) { copyConstruct<bsl::allocator<TARGET_TYPE> >(toBegin, fromBegin, fromEnd, basicAllocator); } template <class ALLOCATOR> inline void ArrayPrimitives::defaultConstruct( typename bsl::allocator_traits<ALLOCATOR>::pointer begin, size_type numElements, ALLOCATOR allocator) { BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); BSLS_ASSERT_SAFE(begin || 0 == numElements); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bsl::is_fundamental<TargetType>::value || bsl::is_enum<TargetType>::value || bsl::is_pointer<TargetType>::value #if !defined(BSLALG_ARRAYPRIMITIVES_NON_ZERO_NULL_VALUE_FOR_MEMBER_POINTERS) || bsl::is_member_pointer<TargetType>::value #endif ? Imp::e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS : bsl::is_trivially_copyable<TargetType>::value && bsl::is_trivially_default_constructible<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::defaultConstruct(begin, numElements, allocator, (bslmf::MetaInt<k_VALUE>*)0); } template <class TARGET_TYPE> inline void ArrayPrimitives::defaultConstruct(TARGET_TYPE *begin, size_type numElements, bslma::Allocator *basicAllocator) { defaultConstruct<bsl::allocator<TARGET_TYPE> >(begin, numElements, basicAllocator); } template <class ALLOCATOR> inline void ArrayPrimitives::destructiveMove( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator) { BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin, fromEnd)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::destructiveMove(toBegin, fromBegin, fromEnd, allocator, (bslmf::MetaInt<k_VALUE>*)0); } template <class TARGET_TYPE> inline void ArrayPrimitives::destructiveMove(TARGET_TYPE *toBegin, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, bslma::Allocator *basicAllocator) { destructiveMove<bsl::allocator<TARGET_TYPE> >(toBegin, fromBegin, fromEnd, basicAllocator); } #if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES // {{{ BEGIN GENERATED CODE // Command line: sim_cpp11_features.pl bslalg_arrayprimitives.h #ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT #define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT 10 #endif #ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D #define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT #endif #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 0 template <class ALLOCATOR> void ArrayPrimitives::destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator) { typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *fromEndPtr = fromEnd; TargetType *toPositionBegin = toBegin + (position - fromBegin); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toPositionBegin); TargetType *toPositionEnd = toPositionBegin + 1; AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin, toPositionEnd, allocator); destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; guard.moveEnd(fromEnd - position); destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; guard.release(); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 0 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 1 template <class ALLOCATOR, class ARGS_01> void ArrayPrimitives::destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01) { typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *fromEndPtr = fromEnd; TargetType *toPositionBegin = toBegin + (position - fromBegin); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toPositionBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01)); TargetType *toPositionEnd = toPositionBegin + 1; AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin, toPositionEnd, allocator); destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; guard.moveEnd(fromEnd - position); destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; guard.release(); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 1 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 2 template <class ALLOCATOR, class ARGS_01, class ARGS_02> void ArrayPrimitives::destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02) { typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *fromEndPtr = fromEnd; TargetType *toPositionBegin = toBegin + (position - fromBegin); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toPositionBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02)); TargetType *toPositionEnd = toPositionBegin + 1; AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin, toPositionEnd, allocator); destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; guard.moveEnd(fromEnd - position); destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; guard.release(); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 2 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 3 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03> void ArrayPrimitives::destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03) { typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *fromEndPtr = fromEnd; TargetType *toPositionBegin = toBegin + (position - fromBegin); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toPositionBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03)); TargetType *toPositionEnd = toPositionBegin + 1; AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin, toPositionEnd, allocator); destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; guard.moveEnd(fromEnd - position); destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; guard.release(); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 3 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 4 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04> void ArrayPrimitives::destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04) { typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *fromEndPtr = fromEnd; TargetType *toPositionBegin = toBegin + (position - fromBegin); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toPositionBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04,arguments_04)); TargetType *toPositionEnd = toPositionBegin + 1; AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin, toPositionEnd, allocator); destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; guard.moveEnd(fromEnd - position); destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; guard.release(); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 4 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 5 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05> void ArrayPrimitives::destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05) { typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *fromEndPtr = fromEnd; TargetType *toPositionBegin = toBegin + (position - fromBegin); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toPositionBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04,arguments_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05,arguments_05)); TargetType *toPositionEnd = toPositionBegin + 1; AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin, toPositionEnd, allocator); destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; guard.moveEnd(fromEnd - position); destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; guard.release(); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 5 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 6 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06> void ArrayPrimitives::destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06) { typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *fromEndPtr = fromEnd; TargetType *toPositionBegin = toBegin + (position - fromBegin); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toPositionBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04,arguments_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05,arguments_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06,arguments_06)); TargetType *toPositionEnd = toPositionBegin + 1; AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin, toPositionEnd, allocator); destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; guard.moveEnd(fromEnd - position); destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; guard.release(); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 6 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 7 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07> void ArrayPrimitives::destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07) { typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *fromEndPtr = fromEnd; TargetType *toPositionBegin = toBegin + (position - fromBegin); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toPositionBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04,arguments_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05,arguments_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06,arguments_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07,arguments_07)); TargetType *toPositionEnd = toPositionBegin + 1; AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin, toPositionEnd, allocator); destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; guard.moveEnd(fromEnd - position); destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; guard.release(); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 7 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 8 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08> void ArrayPrimitives::destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08) { typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *fromEndPtr = fromEnd; TargetType *toPositionBegin = toBegin + (position - fromBegin); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toPositionBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04,arguments_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05,arguments_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06,arguments_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07,arguments_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08,arguments_08)); TargetType *toPositionEnd = toPositionBegin + 1; AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin, toPositionEnd, allocator); destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; guard.moveEnd(fromEnd - position); destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; guard.release(); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 8 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 9 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09> void ArrayPrimitives::destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09) { typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *fromEndPtr = fromEnd; TargetType *toPositionBegin = toBegin + (position - fromBegin); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toPositionBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04,arguments_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05,arguments_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06,arguments_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07,arguments_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08,arguments_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09,arguments_09)); TargetType *toPositionEnd = toPositionBegin + 1; AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin, toPositionEnd, allocator); destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; guard.moveEnd(fromEnd - position); destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; guard.release(); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 9 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 10 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09, class ARGS_10> void ArrayPrimitives::destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) arguments_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) arguments_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) arguments_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) arguments_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) arguments_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) arguments_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) arguments_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) arguments_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) arguments_09, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) arguments_10) { typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *fromEndPtr = fromEnd; TargetType *toPositionBegin = toBegin + (position - fromBegin); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toPositionBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,arguments_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,arguments_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,arguments_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04,arguments_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05,arguments_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06,arguments_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07,arguments_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08,arguments_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09,arguments_09), BSLS_COMPILERFEATURES_FORWARD(ARGS_10,arguments_10)); TargetType *toPositionEnd = toPositionBegin + 1; AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin, toPositionEnd, allocator); destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; guard.moveEnd(fromEnd - position); destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; guard.release(); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_D >= 10 #else // The generated code below is a workaround for the absence of perfect // forwarding in some compilers. template <class ALLOCATOR, class... ARGS> void ArrayPrimitives::destructiveMoveAndEmplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... arguments) { typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *fromEndPtr = fromEnd; TargetType *toPositionBegin = toBegin + (position - fromBegin); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toPositionBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS,arguments)...); TargetType *toPositionEnd = toPositionBegin + 1; AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin, toPositionEnd, allocator); destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; guard.moveEnd(fromEnd - position); destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; guard.release(); } // }}} END GENERATED CODE #endif template <class ALLOCATOR> void ArrayPrimitives::destructiveMoveAndInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, size_type numElements, ALLOCATOR allocator) { // Key to the transformation diagrams: //.. // A...H original contents of '[fromBegin, fromEnd)' ("source") // v...v default-constructed values ("input") // ; ... contents of '[toBegin, toEnd)' ("destination") // ..:.. position of 'fromEndPtr' in the input // _____ uninitialized array elements // [...] part of array protected by an exception guard object //.. typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *fromEndPtr = fromEnd; // Note: Construct default values. //.. // Transformation: ABCDEFGH: ; _____________[] // => ABCDEFGH: ; ____[vvvvv]____ //.. TargetType *toPositionBegin = toBegin + (position - fromBegin); defaultConstruct(toPositionBegin, numElements, allocator); TargetType *toPositionEnd = toPositionBegin + numElements; AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin, toPositionEnd, allocator); //.. // Transformation: ABCDEFGH: ; ____[vvvvv]____ // => ABCD:____ ; ____[vvvvvEFGH] //.. destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; // shorten input range after partial destruction guard.moveEnd(fromEnd - position); // toEnd //.. // Transformation: ABCD:____ ; ____[vvvvvEFGH] // => :________ ; ABCDvvvvvEFGH[] //.. destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; // empty input range after final destruction guard.release(); } template <class TARGET_TYPE> inline void ArrayPrimitives::destructiveMoveAndInsert( TARGET_TYPE *toBegin, TARGET_TYPE **fromEndPtr, TARGET_TYPE *fromBegin, TARGET_TYPE *position, TARGET_TYPE *fromEnd, size_type numElements, bslma::Allocator *basicAllocator) { destructiveMoveAndInsert<bsl::allocator<TARGET_TYPE> >(toBegin, fromEndPtr, fromBegin, position, fromEnd, numElements, basicAllocator); } template <class ALLOCATOR> void ArrayPrimitives::destructiveMoveAndInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, const typename bsl::allocator_traits<ALLOCATOR>::value_type& value, size_type numElements, ALLOCATOR allocator) { // Key to the transformation diagrams: //.. // A...H original contents of '[fromBegin, fromEnd)' ("source") // v...v copies of 'value' ("input") // ; ... contents of '[toBegin, toEnd)' ("destination") // ..:.. position of 'fromEndPtr' in the input // _____ uninitialized array elements // [...] part of array protected by an exception guard object //.. typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *fromEndPtr = fromEnd; // Note: Construct copies of 'value' first in case 'value' is a reference // in the input range, which would be invalidated by any of the following // moves. // //.. // Transformation: ABCDEFGH: ; _____________[] // => ABCDEFGH: ; ____[vvvvv]____ //.. TargetType *toPositionBegin = toBegin + (position - fromBegin); uninitializedFillN(toPositionBegin, numElements, value, allocator); TargetType *toPositionEnd = toPositionBegin + numElements; AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin, toPositionEnd, allocator); //.. // Transformation: ABCDEFGH: ; ____[vvvvv]____ // => ABCD:____ ; ____[vvvvvEFGH] //.. destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; // shorten input range after partial destruction guard.moveEnd(fromEnd - position); // toEnd //.. // Transformation: ABCD:____ ; ____[vvvvvEFGH] // => :________ ; ABCDvvvvvEFGH[] //.. destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; // empty input range after final destruction guard.release(); } template <class TARGET_TYPE> void ArrayPrimitives::destructiveMoveAndInsert( TARGET_TYPE *toBegin, TARGET_TYPE **fromEndPtr, TARGET_TYPE *fromBegin, TARGET_TYPE *position, TARGET_TYPE *fromEnd, const TARGET_TYPE& value, size_type numElements, bslma::Allocator *basicAllocator) { destructiveMoveAndInsert<bsl::allocator<TARGET_TYPE> >(toBegin, fromEndPtr, fromBegin, position, fromEnd, value, numElements, basicAllocator); } template <class ALLOCATOR, class FWD_ITER> void ArrayPrimitives::destructiveMoveAndInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, FWD_ITER first, FWD_ITER last, size_type numElements, ALLOCATOR allocator) { // Key to the transformation diagrams: //.. // A...H original contents of '[fromBegin, fromEnd)' ("source") // t...z original contents of '[first, last)' ("input") // ; ... contents of '[toBegin, toEnd)' ("destination") // ..:.. position of 'fromEndPtr' in the input // _____ uninitialized array elements // [...] part of array protected by an exception guard object //.. typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *fromEndPtr = fromEnd; // Note: Construct copies of 'value' first in case 'value' is a reference // in the input range, which would be invalidated by any of the following // moves: //.. // Transformation: ABCDEFGH: ; _________[]____ // => ABCDEFGH: ; ____[tuvxy]____ //.. TargetType *toPositionBegin = toBegin + (position - fromBegin); copyConstruct(toPositionBegin, first, last, allocator); TargetType *toPositionEnd = toPositionBegin + numElements; AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionBegin, toPositionEnd, allocator); //.. // Transformation: ABCDEFGH: ; ____[tuvxy]____ // => ABCD:____ ; ____[tuvxyEFGH] //.. destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; // shorten input range after partial destruction guard.moveEnd(fromEnd - position); // toEnd //.. // Transformation: ABCD:____ ; ____[tuvxyEFGH] // => :________ ; ABCDtuvxyEFGH[] //.. destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; // empty input range after final destruction guard.release(); } template <class TARGET_TYPE, class FWD_ITER> inline void ArrayPrimitives::destructiveMoveAndInsert( TARGET_TYPE *toBegin, TARGET_TYPE **fromEndPtr, TARGET_TYPE *fromBegin, TARGET_TYPE *position, TARGET_TYPE *fromEnd, FWD_ITER first, FWD_ITER last, size_type numElements, bslma::Allocator *basicAllocator) { destructiveMoveAndInsert<bsl::allocator<TARGET_TYPE> >(toBegin, fromEndPtr, fromBegin, position, fromEnd, first, last, numElements, basicAllocator); } template <class ALLOCATOR> void ArrayPrimitives::destructiveMoveAndMoveInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer *lastPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer position, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, typename bsl::allocator_traits<ALLOCATOR>::pointer first, typename bsl::allocator_traits<ALLOCATOR>::pointer last, size_type numElements, ALLOCATOR allocator) { // Key to the transformation diagrams: //.. // A...H original contents of '[fromBegin, fromEnd)' ("source") // t...z original contents of '[first, last)' ("input") // ; ... contents of '[toBegin, toEnd)' ("destination") // ..:.. position of 'fromEndPtr' in the input // _____ uninitialized array elements // [...] part of array protected by an exception guard object //.. typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; *lastPtr = last; *fromEndPtr = fromEnd; //.. // Transformation: ABCDEFGH: ; _____________[] // => ABCD:____ ; _________[EFGH] //.. TargetType *toPositionBegin = toBegin + (position - fromBegin); TargetType *toPositionEnd = toPositionBegin + numElements; destructiveMove(toPositionEnd, position, fromEnd, allocator); *fromEndPtr = position; // shorten input range after partial destruction AutoArrayDestructor<TargetType, ALLOCATOR> guard(toPositionEnd, toPositionEnd + (fromEnd - position), allocator); //.. // Transformation: ABCD:____ ; _________[EFGH] // => ABCD:____ ; _____[tuvwEFGH] //.. destructiveMove(toPositionBegin, first, last, allocator); *lastPtr = first; guard.moveBegin(-static_cast<difference_type>(numElements)); //.. // Transformation: ABCD:____ ; ____[tuvwEFGH] // => :________ ; ABCDtuvwEFGH[] //.. destructiveMove(toBegin, fromBegin, position, allocator); *fromEndPtr = fromBegin; // empty input range after final destruction guard.release(); } template <class TARGET_TYPE> inline void ArrayPrimitives::destructiveMoveAndMoveInsert( TARGET_TYPE *toBegin, TARGET_TYPE **fromEndPtr, TARGET_TYPE **lastPtr, TARGET_TYPE *fromBegin, TARGET_TYPE *position, TARGET_TYPE *fromEnd, TARGET_TYPE *first, TARGET_TYPE *last, size_type numElements, bslma::Allocator *basicAllocator) { destructiveMoveAndMoveInsert<bsl::allocator<TARGET_TYPE> >(toBegin, fromEndPtr, lastPtr, fromBegin, position, fromEnd, first, last, numElements, basicAllocator); } #if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES // {{{ BEGIN GENERATED CODE // Command line: sim_cpp11_features.pl bslalg_arrayprimitives.h #ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT #define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT 10 #endif #ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E #define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT #endif #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 0 template <class ALLOCATOR> inline void ArrayPrimitives::emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bsl::is_trivially_copyable<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::emplace( toBegin, toEnd, allocator, (bslmf::MetaInt<k_VALUE> *)0); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 0 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 1 template <class ALLOCATOR, class ARGS_01> inline void ArrayPrimitives::emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bsl::is_trivially_copyable<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::emplace( toBegin, toEnd, allocator, (bslmf::MetaInt<k_VALUE> *)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 1 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 2 template <class ALLOCATOR, class ARGS_01, class ARGS_02> inline void ArrayPrimitives::emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bsl::is_trivially_copyable<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::emplace( toBegin, toEnd, allocator, (bslmf::MetaInt<k_VALUE> *)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 2 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 3 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03> inline void ArrayPrimitives::emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bsl::is_trivially_copyable<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::emplace( toBegin, toEnd, allocator, (bslmf::MetaInt<k_VALUE> *)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 3 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 4 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04> inline void ArrayPrimitives::emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bsl::is_trivially_copyable<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::emplace( toBegin, toEnd, allocator, (bslmf::MetaInt<k_VALUE> *)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 4 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 5 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05> inline void ArrayPrimitives::emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bsl::is_trivially_copyable<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::emplace( toBegin, toEnd, allocator, (bslmf::MetaInt<k_VALUE> *)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 5 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 6 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06> inline void ArrayPrimitives::emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bsl::is_trivially_copyable<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::emplace( toBegin, toEnd, allocator, (bslmf::MetaInt<k_VALUE> *)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 6 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 7 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07> inline void ArrayPrimitives::emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bsl::is_trivially_copyable<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::emplace( toBegin, toEnd, allocator, (bslmf::MetaInt<k_VALUE> *)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 7 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 8 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08> inline void ArrayPrimitives::emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bsl::is_trivially_copyable<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::emplace( toBegin, toEnd, allocator, (bslmf::MetaInt<k_VALUE> *)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 8 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 9 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09> inline void ArrayPrimitives::emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bsl::is_trivially_copyable<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::emplace( toBegin, toEnd, allocator, (bslmf::MetaInt<k_VALUE> *)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 9 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 10 template <class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09, class ARGS_10> inline void ArrayPrimitives::emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bsl::is_trivially_copyable<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::emplace( toBegin, toEnd, allocator, (bslmf::MetaInt<k_VALUE> *)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09), BSLS_COMPILERFEATURES_FORWARD(ARGS_10, args_10)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 10 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 0 template <class TARGET_TYPE> inline void ArrayPrimitives::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *basicAllocator) { emplace<bsl::allocator<TARGET_TYPE> >( toBegin, toEnd, basicAllocator); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 0 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 1 template <class TARGET_TYPE, class ARGS_01> inline void ArrayPrimitives::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *basicAllocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01) { emplace<bsl::allocator<TARGET_TYPE> >( toBegin, toEnd, basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 1 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 2 template <class TARGET_TYPE, class ARGS_01, class ARGS_02> inline void ArrayPrimitives::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *basicAllocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02) { emplace<bsl::allocator<TARGET_TYPE> >( toBegin, toEnd, basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 2 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 3 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03> inline void ArrayPrimitives::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *basicAllocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03) { emplace<bsl::allocator<TARGET_TYPE> >( toBegin, toEnd, basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 3 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 4 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04> inline void ArrayPrimitives::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *basicAllocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04) { emplace<bsl::allocator<TARGET_TYPE> >( toBegin, toEnd, basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 4 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 5 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05> inline void ArrayPrimitives::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *basicAllocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05) { emplace<bsl::allocator<TARGET_TYPE> >( toBegin, toEnd, basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 5 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 6 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06> inline void ArrayPrimitives::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *basicAllocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06) { emplace<bsl::allocator<TARGET_TYPE> >( toBegin, toEnd, basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 6 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 7 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07> inline void ArrayPrimitives::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *basicAllocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07) { emplace<bsl::allocator<TARGET_TYPE> >( toBegin, toEnd, basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 7 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 8 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08> inline void ArrayPrimitives::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *basicAllocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08) { emplace<bsl::allocator<TARGET_TYPE> >( toBegin, toEnd, basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 8 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 9 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09> inline void ArrayPrimitives::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *basicAllocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09) { emplace<bsl::allocator<TARGET_TYPE> >( toBegin, toEnd, basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 9 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 10 template <class TARGET_TYPE, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09, class ARGS_10> inline void ArrayPrimitives::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *basicAllocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10) { emplace<bsl::allocator<TARGET_TYPE> >( toBegin, toEnd, basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09), BSLS_COMPILERFEATURES_FORWARD(ARGS_10, args_10)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_E >= 10 #else // The generated code below is a workaround for the absence of perfect // forwarding in some compilers. template <class ALLOCATOR, class... ARGS> inline void ArrayPrimitives::emplace( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, ALLOCATOR allocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bsl::is_trivially_copyable<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::emplace( toBegin, toEnd, allocator, (bslmf::MetaInt<k_VALUE> *)0, BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...); } template <class TARGET_TYPE, class... ARGS> inline void ArrayPrimitives::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslma::Allocator *basicAllocator, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args) { emplace<bsl::allocator<TARGET_TYPE> >( toBegin, toEnd, basicAllocator, BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...); } // }}} END GENERATED CODE #endif template <class ALLOCATOR> inline void ArrayPrimitives::erase( typename bsl::allocator_traits<ALLOCATOR>::pointer first, typename bsl::allocator_traits<ALLOCATOR>::pointer middle, typename bsl::allocator_traits<ALLOCATOR>::pointer last, ALLOCATOR allocator) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(first, middle)); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(middle, last)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; if (first == middle) { // erasing empty range O(1) versus O(N): Do not // remove! return; // RETURN } enum { k_VALUE = bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::erase(first, middle, last, allocator, (bslmf::MetaInt<k_VALUE>*)0); } template <class TARGET_TYPE> inline void ArrayPrimitives::erase(TARGET_TYPE *first, TARGET_TYPE *middle, TARGET_TYPE *last, bslma::Allocator *basicAllocator) { erase<bsl::allocator<TARGET_TYPE> >(first, middle, last, basicAllocator); } template <class ALLOCATOR> inline void ArrayPrimitives::insert( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, bslmf::MovableRef< typename bsl::allocator_traits<ALLOCATOR>::value_type> value, ALLOCATOR allocator) { BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; if (toBegin != toEnd) { // Insert in the middle. Note that there is no strong exception // guarantee if copy constructor, move constructor, or assignment // operator throw. enum { k_VALUE = bsl::is_trivially_copyable<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::shiftAndInsert(toBegin, toEnd, bslmf::MovableRefUtil::move(value), allocator, (bslmf::MetaInt<k_VALUE>*)0); } else { // toBegin == toEnd bsl::allocator_traits<ALLOCATOR>::construct( allocator, toBegin, bslmf::MovableRefUtil::move(value)); } } template <class TARGET_TYPE> inline void ArrayPrimitives::insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, bslmf::MovableRef<TARGET_TYPE> value, bslma::Allocator *basicAllocator) { insert<bsl::allocator<TARGET_TYPE> >(toBegin, toEnd, bslmf::MovableRefUtil::move(value), basicAllocator); } template <class ALLOCATOR> void ArrayPrimitives::insert( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, const typename bsl::allocator_traits<ALLOCATOR>::value_type& value, size_type numElements, ALLOCATOR allocator) { BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; if (0 == numElements) { return; // RETURN } enum { k_VALUE = bsl::is_trivially_copyable<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::insert(toBegin, toEnd, value, numElements, allocator, (bslmf::MetaInt<k_VALUE>*)0); } template <class TARGET_TYPE> inline void ArrayPrimitives::insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, const TARGET_TYPE& value, size_type numElements, bslma::Allocator *basicAllocator) { insert<bsl::allocator<TARGET_TYPE> >(toBegin, toEnd, value, numElements, basicAllocator); } template <class ALLOCATOR, class FWD_ITER> void ArrayPrimitives::insert( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, FWD_ITER fromBegin, FWD_ITER fromEnd, size_type numElements, ALLOCATOR allocator) { if (0 == numElements) { return; // RETURN } typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; BSLMF_ASSERT(!bsl::is_pointer<FWD_ITER>::value); typedef typename FWD_ITER::value_type FwdTarget; // Overload resolution will handle the case where 'FWD_ITER' is a raw // pointer, so we need handle only user-defined iterators. As 'bslalg' // is levelized below 'bslstl' we cannot use 'iterator_traits', but // rely on the same property as 'iterator_traits' that this typedef // must be defined for any standard-conforming iterator, unless the // iterator explicitly specialized the 'std::iterator_traits' template. // In practice, iterators always prefer to provide the member typedef // than specialize the traits as it is a much simpler implementation, // so this assumption is good enough. // // Also note that as we know that 'FWD_ITER' is not a pointer, then we // cannot take advantage of bitwise copying as we do not have pointers // to pass to the 'memcpy' describing the whole range. It is not worth // the effort to try to bitwise copy one element at a time. typedef typename bsl::remove_pointer<TargetType>::type RemovePtrTarget; // We want to detect the special case of copying function pointers to // 'void *' or 'const void *' pointers. enum { k_ITER_TO_FUNC_PTRS = bslmf::IsFunctionPointer<FwdTarget>::value, k_TARGET_IS_VOID_PTR = bsl::is_pointer<TargetType>::value && bsl::is_void<RemovePtrTarget>::value, k_VALUE = k_ITER_TO_FUNC_PTRS && k_TARGET_IS_VOID_PTR ? Imp::e_IS_ITERATOR_TO_FUNCTION_POINTER : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::insert(toBegin, toEnd, fromBegin, fromEnd, numElements, allocator, (bslmf::MetaInt<k_VALUE>*)0); } template <class TARGET_TYPE, class FWD_ITER> inline void ArrayPrimitives::insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, FWD_ITER fromBegin, FWD_ITER fromEnd, size_type numElements, bslma::Allocator *basicAllocator) { insert<bsl::allocator<TARGET_TYPE> >(toBegin, toEnd, fromBegin, fromEnd, numElements, basicAllocator); } template <class ALLOCATOR, class SOURCE_TYPE> void ArrayPrimitives::insert( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, SOURCE_TYPE *fromBegin, SOURCE_TYPE *fromEnd, size_type numElements, ALLOCATOR allocator) { if (0 == numElements) { return; // RETURN } typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_ARE_PTRS_TO_PTRS = bsl::is_pointer<TargetType>::value && bsl::is_pointer<SOURCE_TYPE>::value, k_IS_BITWISEMOVEABLE = bslmf::IsBitwiseMoveable<TargetType>::value, k_IS_BITWISECOPYABLE = ArrayPrimitives_CanBitwiseCopy<SOURCE_TYPE, TargetType>::value, k_VALUE = k_ARE_PTRS_TO_PTRS ? Imp::e_IS_POINTER_TO_POINTER : k_IS_BITWISECOPYABLE ? Imp::e_BITWISE_COPYABLE_TRAITS : k_IS_BITWISEMOVEABLE ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::insert(toBegin, toEnd, fromBegin, fromEnd, numElements, allocator, (bslmf::MetaInt<k_VALUE>*)0); } template <class TARGET_TYPE, class SOURCE_TYPE> inline void ArrayPrimitives::insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, SOURCE_TYPE *fromBegin, SOURCE_TYPE *fromEnd, size_type numElements, bslma::Allocator *basicAllocator) { insert<bsl::allocator<TARGET_TYPE> >(toBegin, toEnd, fromBegin, fromEnd, numElements, basicAllocator); } template <class ALLOCATOR> inline void ArrayPrimitives::moveConstruct( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, ALLOCATOR allocator) { BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd); typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bsl::is_trivially_copyable<TargetType>::value ? Imp::e_BITWISE_COPYABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::moveConstruct(toBegin, fromBegin, fromEnd, allocator, (bslmf::MetaInt<k_VALUE>*)0); } template <class TARGET_TYPE> inline void ArrayPrimitives::moveConstruct(TARGET_TYPE *toBegin, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, bslma::Allocator *basicAllocator) { moveConstruct<bsl::allocator<TARGET_TYPE> >(toBegin, fromBegin, fromEnd, basicAllocator); } template <class ALLOCATOR> inline void ArrayPrimitives::moveInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer toBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer toEnd, typename bsl::allocator_traits<ALLOCATOR>::pointer *fromEndPtr, typename bsl::allocator_traits<ALLOCATOR>::pointer fromBegin, typename bsl::allocator_traits<ALLOCATOR>::pointer fromEnd, size_type numElements, ALLOCATOR allocator) { typedef typename bsl::allocator_traits<ALLOCATOR>::value_type TargetType; enum { k_VALUE = bslmf::IsBitwiseMoveable<TargetType>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::moveInsert(toBegin, toEnd, fromEndPtr, fromBegin, fromEnd, numElements, allocator, (bslmf::MetaInt<k_VALUE>*)0); } template <class TARGET_TYPE> inline void ArrayPrimitives::moveInsert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, TARGET_TYPE **fromEndPtr, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, size_type numElements, bslma::Allocator *basicAllocator) { moveInsert<bsl::allocator<TARGET_TYPE> >(toBegin, toEnd, fromEndPtr, fromBegin, fromEnd, numElements, basicAllocator); } template <class TARGET_TYPE> inline void ArrayPrimitives::rotate(TARGET_TYPE *first, TARGET_TYPE *middle, TARGET_TYPE *last) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(first, middle)); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(middle, last)); enum { k_VALUE = bslmf::IsBitwiseMoveable<TARGET_TYPE>::value ? Imp::e_BITWISE_MOVEABLE_TRAITS : Imp::e_NIL_TRAITS }; ArrayPrimitives_Imp::rotate(first, middle, last, (bslmf::MetaInt<k_VALUE>*)0); } // -------------------------- // struct ArrayPrimitives_Imp // -------------------------- // CLASS METHODS template <class TARGET_TYPE> inline void ArrayPrimitives_Imp::assign(TARGET_TYPE *srcStart, TARGET_TYPE *srcEnd, TARGET_TYPE& value) { for ( ; srcStart != srcEnd; ++srcStart) { *srcStart = value; } } template <class FORWARD_ITERATOR> inline bool ArrayPrimitives_Imp::isInvalidRange(FORWARD_ITERATOR, FORWARD_ITERATOR) { // Ideally would dispatch on random_access_iterator_tag to support // generalized random access iterators, but we are constrained by 'bsl' // levelization to not depend on 'bsl_iterator.h'. As the intent is to // detect invalid ranges in assertions, the conservative choice is to // return 'false' always. Note that this differs from the pointers case // below, which also disallows empty ranges. return false; } template <class TARGET_TYPE> inline bool ArrayPrimitives_Imp::isInvalidRange(TARGET_TYPE *begin, TARGET_TYPE *end) { return !begin != !end || begin > end; } template <class TARGET_TYPE> inline void ArrayPrimitives_Imp::reverseAssign(TARGET_TYPE *dest, TARGET_TYPE *srcStart, TARGET_TYPE *srcEnd) { TARGET_TYPE *destEnd = srcEnd - srcStart + dest; while (srcStart != srcEnd) { *--destEnd = *--srcEnd; } } // *** 'uninitializedFillN' overloads: *** inline void ArrayPrimitives_Imp::uninitializedFillN( bool *begin, bool value, size_type numElements, void *, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); BSLMF_ASSERT(sizeof(bool) == 1); if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numElements != 0)) { std::memset(reinterpret_cast<char *>(begin), // odd, why not 'void *'? static_cast<char>(value), numElements); } } inline void ArrayPrimitives_Imp::uninitializedFillN( char *begin, char value, size_type numElements, void *, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numElements != 0)) { std::memset(begin, value, numElements); } } inline void ArrayPrimitives_Imp::uninitializedFillN( unsigned char *begin, unsigned char value, size_type numElements, void *, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numElements != 0)) { std::memset(begin, value, numElements); } } inline void ArrayPrimitives_Imp::uninitializedFillN( signed char *begin, signed char value, size_type numElements, void *, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numElements != 0)) { std::memset(begin, value, numElements); } } inline void ArrayPrimitives_Imp::uninitializedFillN( wchar_t *begin, wchar_t value, size_type numElements, void *, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numElements != 0)) { std::wmemset(begin, value, numElements); } } inline void ArrayPrimitives_Imp::uninitializedFillN( unsigned short *begin, unsigned short value, size_type numElements, void *, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); uninitializedFillN(reinterpret_cast<short *>(begin), static_cast<short>(value), numElements, (void *)0, (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0); } inline void ArrayPrimitives_Imp::uninitializedFillN( unsigned int *begin, unsigned int value, size_type numElements, void *, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); uninitializedFillN(reinterpret_cast<int *>(begin), static_cast<int>(value), numElements, (void *)0, (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0); } inline void ArrayPrimitives_Imp::uninitializedFillN( long *begin, long value, size_type numElements, void *, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); #if defined(BSLS_PLATFORM_CPU_64_BIT) && !defined(BSLS_PLATFORM_OS_WINDOWS) uninitializedFillN(reinterpret_cast<bsls::Types::Int64 *>(begin), static_cast<bsls::Types::Int64>(value), numElements); #else uninitializedFillN(reinterpret_cast<int *>(begin), static_cast<int>(value), numElements, (void *)0, (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0); #endif } inline void ArrayPrimitives_Imp::uninitializedFillN( unsigned long *begin, unsigned long value, size_type numElements, void *, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); #if defined(BSLS_PLATFORM_CPU_64_BIT) && !defined(BSLS_PLATFORM_OS_WINDOWS) uninitializedFillN(reinterpret_cast<bsls::Types::Int64 *>(begin), static_cast<bsls::Types::Int64>(value), numElements, (void *)0, (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER>*)0); #else uninitializedFillN(reinterpret_cast<int *>(begin), static_cast<int>(value), numElements, (void *)0, (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0); #endif } inline void ArrayPrimitives_Imp::uninitializedFillN( bsls::Types::Uint64 *begin, bsls::Types::Uint64 value, size_type numElements, void *, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); uninitializedFillN(reinterpret_cast<bsls::Types::Int64 *>(begin), value, numElements, (void *)0, (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0); } template <class TARGET_TYPE> inline void ArrayPrimitives_Imp::uninitializedFillN( TARGET_TYPE **begin, TARGET_TYPE *value, size_type numElements, void *, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); // Note: 'const'-correctness is respected because the next overload picks // up the 'const TARGET_TYPE' and will be a better match. Note that we // cannot cast to 'const void **' (one would have to add 'const' at every // level, not just the innermost; i.e., 'const void *const *' would be // correct, 'const void **' is not [C++ Standard, 4.4 Qualification // conversions]). uninitializedFillN(reinterpret_cast<void **>(begin), static_cast<void *>(value), numElements, (void *)0, (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0); } template <class TARGET_TYPE> inline void ArrayPrimitives_Imp::uninitializedFillN( const TARGET_TYPE **begin, const TARGET_TYPE *value, size_type numElements, void *, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); // While it seems that this overload is subsumed by the previous template, // SunPro does not detect it. uninitializedFillN(reinterpret_cast<const void **>(begin), static_cast<const void *>(value), numElements, (void *)0, (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0); } template <class TARGET_TYPE> inline void ArrayPrimitives_Imp::uninitializedFillN( volatile TARGET_TYPE **begin, volatile TARGET_TYPE *value, size_type numElements, void *, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); // While it seems that this overload is subsumed by the previous template, // SunPro does not detect it. uninitializedFillN(reinterpret_cast<volatile void **>(begin), static_cast<volatile void *>(value), numElements, (void *)0, (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0); } template <class TARGET_TYPE> inline void ArrayPrimitives_Imp::uninitializedFillN( const volatile TARGET_TYPE **begin, const volatile TARGET_TYPE *value, size_type numElements, void *, bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); // While it seems that this overload is subsumed by the previous template, // SunPro does not detect it. uninitializedFillN(reinterpret_cast<const volatile void **>(begin), static_cast<const volatile void *>(value), numElements, (void *)0, (bslmf::MetaInt<e_IS_FUNDAMENTAL_OR_POINTER> *)0); } template <class TARGET_TYPE, class ALLOCATOR> void ArrayPrimitives_Imp::uninitializedFillN( TARGET_TYPE *begin, const TARGET_TYPE& value, size_type numElements, ALLOCATOR *, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (0 == numElements) { return; // RETURN } const char *valueBuffer = reinterpret_cast<const char *>(BSLS_UTIL_ADDRESSOF(value)); std::memcpy((void *)begin, valueBuffer, sizeof(TARGET_TYPE)); bitwiseFillN(reinterpret_cast<char *>(begin), sizeof(TARGET_TYPE), sizeof(TARGET_TYPE) * numElements); } template <class TARGET_TYPE, class ALLOCATOR> void ArrayPrimitives_Imp::uninitializedFillN( TARGET_TYPE *begin, const TARGET_TYPE& value, size_type numElements, ALLOCATOR *allocator, bslmf::MetaInt<e_NIL_TRAITS> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); BSLS_ASSERT_SAFE(allocator); if (0 == numElements) { return; // RETURN } AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(begin, begin, *allocator); TARGET_TYPE *end = begin + numElements; do { bsl::allocator_traits<ALLOCATOR>::construct(*allocator, begin, value); begin = guard.moveEnd(1); } while (begin != end); guard.release(); } // *** 'copyConstruct' overloads: *** template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR> inline void ArrayPrimitives_Imp::copyConstruct( TARGET_TYPE *toBegin, FWD_ITER fromBegin, FWD_ITER fromEnd, ALLOCATOR allocator, bslmf::MetaInt<e_IS_POINTER_TO_POINTER> *) { // We may be casting a function pointer to a 'void *' here, so this won't // work if we port to an architecture where the two are of different sizes. BSLMF_ASSERT(sizeof(void *) == sizeof(void (*)())); typedef typename bsl::remove_cv< typename bsl::remove_pointer<TARGET_TYPE>::type>::type NcPtrType; typedef typename bsl::remove_cv< typename bsl::remove_pointer< typename bsl::remove_pointer<FWD_ITER>::type>::type>::type NcIter; #if defined(BSLALG_ARRAYPRIMITIVES_CANNOT_REMOVE_POINTER_FROM_FUNCTION_POINTER) // fall back on traditional C-style casts. copyConstruct((void * *)toBegin, (void * const *)fromBegin, (void * const *)fromEnd, allocator, (bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *) 0); #else copyConstruct( reinterpret_cast<void * *>(const_cast<NcPtrType **>(toBegin)), reinterpret_cast<void * const *>(const_cast<NcIter * const *>(fromBegin)), reinterpret_cast<void * const *>(const_cast<NcIter * const *>(fromEnd)), allocator, (bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *)0); #endif } template <class FWD_ITER, class ALLOCATOR> void ArrayPrimitives_Imp::copyConstruct( void **toBegin, FWD_ITER fromBegin, FWD_ITER fromEnd, ALLOCATOR , bslmf::MetaInt<e_IS_ITERATOR_TO_FUNCTION_POINTER> *) { BSLMF_ASSERT(sizeof(void *) == sizeof(void (*)())); // We will be casting a function pointer to a 'void *', so this won't // work if we port to an architecture where the two are of different // sizes. BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin, fromEnd)); while (fromBegin != fromEnd) { // 'fromBegin' iterates over pointers to functions, which must be // 'reinterpret_cast' to 'void *'. *toBegin = reinterpret_cast<void *>(*fromBegin); ++fromBegin; ++toBegin; } } template <class TARGET_TYPE, class ALLOCATOR> inline void ArrayPrimitives_Imp::copyConstruct( TARGET_TYPE *toBegin, const TARGET_TYPE *fromBegin, const TARGET_TYPE *fromEnd, ALLOCATOR , bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *) { BSLS_ASSERT_SAFE(toBegin); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin, fromEnd)); const size_type numBytes = reinterpret_cast<const char*>(fromEnd) - reinterpret_cast<const char*>(fromBegin); if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numBytes != 0)) { std::memcpy((void *)toBegin, fromBegin, numBytes); } } template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR> void ArrayPrimitives_Imp::copyConstruct( TARGET_TYPE *toBegin, FWD_ITER fromBegin, FWD_ITER fromEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *) { BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin, fromEnd)); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, toBegin, allocator); while (fromBegin != fromEnd) { // Note: We are not sure the value type of 'FWD_ITER' is convertible to // 'TARGET_TYPE'. Use 'construct' instead. bsl::allocator_traits<ALLOCATOR>::construct(allocator, toBegin, *fromBegin); ++fromBegin; toBegin = guard.moveEnd(1); } guard.release(); } // *** 'moveConstruct' overloads: *** template <class TARGET_TYPE, class ALLOCATOR> inline void ArrayPrimitives_Imp::moveConstruct( TARGET_TYPE *toBegin, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, ALLOCATOR , bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *) { BSLS_ASSERT_SAFE(toBegin); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin, fromEnd)); const size_type numBytes = reinterpret_cast<const char*>(fromEnd) - reinterpret_cast<const char*>(fromBegin); if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numBytes != 0)) { std::memcpy((void *)toBegin, fromBegin, numBytes); } } template <class TARGET_TYPE, class ALLOCATOR> void ArrayPrimitives_Imp::moveConstruct( TARGET_TYPE *toBegin, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *) { BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin, fromEnd)); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, toBegin, allocator); while (fromBegin != fromEnd) { bsl::allocator_traits<ALLOCATOR>::construct( allocator, toBegin, bslmf::MovableRefUtil::move(*fromBegin)); ++fromBegin; toBegin = guard.moveEnd(1); } guard.release(); } template <class TARGET_TYPE, class ALLOCATOR> void ArrayPrimitives_Imp::moveIfNoexcept( TARGET_TYPE *toBegin, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *) { BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin, fromEnd)); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, toBegin, allocator); while (fromBegin != fromEnd) { bsl::allocator_traits<ALLOCATOR>::construct( allocator, toBegin, bslmf::MovableRefUtil::move_if_noexcept(*fromBegin)); ++fromBegin; toBegin = guard.moveEnd(1); } guard.release(); } // *** 'defaultConstruct' overloads: *** template <class TARGET_TYPE, class ALLOCATOR> inline void ArrayPrimitives_Imp::defaultConstruct( TARGET_TYPE *begin, size_type numElements, ALLOCATOR , bslmf::MetaInt<e_HAS_TRIVIAL_DEFAULT_CTOR_TRAITS> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numElements != 0)) { std::memset(static_cast<void *>(begin), 0, sizeof(TARGET_TYPE) * numElements); } } template <class TARGET_TYPE, class ALLOCATOR> inline void ArrayPrimitives_Imp::defaultConstruct( TARGET_TYPE *begin, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (0 < numElements) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, begin); bitwiseFillN(reinterpret_cast<char *>(begin), sizeof(TARGET_TYPE), numElements * sizeof(TARGET_TYPE)); } } template <class TARGET_TYPE, class ALLOCATOR> void ArrayPrimitives_Imp::defaultConstruct( TARGET_TYPE *begin, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *) { BSLS_ASSERT_SAFE(begin || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(begin, begin, allocator); const TARGET_TYPE *end = begin + numElements; while (begin != end) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, begin); begin = guard.moveEnd(1); } guard.release(); } // *** 'destructiveMove' overloads: *** template <class TARGET_TYPE, class ALLOCATOR> inline void ArrayPrimitives_Imp::destructiveMove( TARGET_TYPE *toBegin, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, ALLOCATOR , bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *) { BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin, fromEnd)); const size_type numBytes = reinterpret_cast<const char*>(fromEnd) - reinterpret_cast<const char*>(fromBegin); if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numBytes != 0)) { std::memcpy((void *)toBegin, fromBegin, numBytes); } } template <class TARGET_TYPE, class ALLOCATOR> inline void ArrayPrimitives_Imp::destructiveMove( TARGET_TYPE *toBegin, TARGET_TYPE *fromBegin, TARGET_TYPE *fromEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *) { BSLS_ASSERT_SAFE(toBegin || fromBegin == fromEnd); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin, fromEnd)); // 'TARGET_TYPE' certainly cannot be bit-wise copyable, so we can save the // compiler some work. moveIfNoexcept(toBegin, fromBegin, fromEnd, allocator, (bslmf::MetaInt<e_NIL_TRAITS>*)0); ArrayDestructionPrimitives::destroy(fromBegin, fromEnd, allocator); } // *** 'emplace' with 'args' overloads: *** #if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES // {{{ BEGIN GENERATED CODE // Command line: sim_cpp11_features.pl bslalg_arrayprimitives.h #ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT #define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT 10 #endif #ifndef BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F #define BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT #endif #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 0 template <class TARGET_TYPE, class ALLOCATOR> inline void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *) { ArrayPrimitives_Imp::emplace(toBegin, toEnd, allocator, (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 0 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 1 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01> inline void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01) { ArrayPrimitives_Imp::emplace(toBegin, toEnd, allocator, (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 1 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 2 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02> inline void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02) { ArrayPrimitives_Imp::emplace(toBegin, toEnd, allocator, (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 2 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 3 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03> inline void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03) { ArrayPrimitives_Imp::emplace(toBegin, toEnd, allocator, (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 3 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 4 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04> inline void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04) { ArrayPrimitives_Imp::emplace(toBegin, toEnd, allocator, (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 4 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 5 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05> inline void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05) { ArrayPrimitives_Imp::emplace(toBegin, toEnd, allocator, (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 5 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 6 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06> inline void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06) { ArrayPrimitives_Imp::emplace(toBegin, toEnd, allocator, (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 6 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 7 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07> inline void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07) { ArrayPrimitives_Imp::emplace(toBegin, toEnd, allocator, (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 7 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 8 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08> inline void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08) { ArrayPrimitives_Imp::emplace(toBegin, toEnd, allocator, (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 8 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 9 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09> inline void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09) { ArrayPrimitives_Imp::emplace(toBegin, toEnd, allocator, (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 9 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 10 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09, class ARGS_10> inline void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10) { ArrayPrimitives_Imp::emplace(toBegin, toEnd, allocator, (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09), BSLS_COMPILERFEATURES_FORWARD(ARGS_10, args_10)); } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 10 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 0 template <class TARGET_TYPE, class ALLOCATOR> void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); size_type numElements = 1; size_type tailLen = toEnd - toBegin; size_type numGuarded = tailLen < numElements ? tailLen : numElements; TARGET_TYPE *destBegin = toBegin + numElements; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) { std::memmove((void *)destBegin, toBegin, tailLen * sizeof(TARGET_TYPE)); } TARGET_TYPE *destEnd = toEnd + numElements; AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, destEnd - numGuarded, destEnd - numGuarded, destEnd, allocator); while (guard.middle() != guard.end()) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, guard.destination()); guard.advance(); } if (tailLen < numElements) { AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin, destEnd, allocator); while (toEnd != destBegin) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, --destBegin); endGuard.moveBegin(-1); } endGuard.release(); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 0 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 1 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01> void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); size_type numElements = 1; size_type tailLen = toEnd - toBegin; size_type numGuarded = tailLen < numElements ? tailLen : numElements; TARGET_TYPE *destBegin = toBegin + numElements; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) { std::memmove((void *)destBegin, toBegin, tailLen * sizeof(TARGET_TYPE)); } TARGET_TYPE *destEnd = toEnd + numElements; AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, destEnd - numGuarded, destEnd - numGuarded, destEnd, allocator); while (guard.middle() != guard.end()) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, guard.destination(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01)); guard.advance(); } if (tailLen < numElements) { AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin, destEnd, allocator); while (toEnd != destBegin) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, --destBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01)); endGuard.moveBegin(-1); } endGuard.release(); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 1 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 2 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02> void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); size_type numElements = 1; size_type tailLen = toEnd - toBegin; size_type numGuarded = tailLen < numElements ? tailLen : numElements; TARGET_TYPE *destBegin = toBegin + numElements; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) { std::memmove((void *)destBegin, toBegin, tailLen * sizeof(TARGET_TYPE)); } TARGET_TYPE *destEnd = toEnd + numElements; AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, destEnd - numGuarded, destEnd - numGuarded, destEnd, allocator); while (guard.middle() != guard.end()) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, guard.destination(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02)); guard.advance(); } if (tailLen < numElements) { AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin, destEnd, allocator); while (toEnd != destBegin) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, --destBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02)); endGuard.moveBegin(-1); } endGuard.release(); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 2 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 3 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03> void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); size_type numElements = 1; size_type tailLen = toEnd - toBegin; size_type numGuarded = tailLen < numElements ? tailLen : numElements; TARGET_TYPE *destBegin = toBegin + numElements; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) { std::memmove((void *)destBegin, toBegin, tailLen * sizeof(TARGET_TYPE)); } TARGET_TYPE *destEnd = toEnd + numElements; AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, destEnd - numGuarded, destEnd - numGuarded, destEnd, allocator); while (guard.middle() != guard.end()) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, guard.destination(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03)); guard.advance(); } if (tailLen < numElements) { AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin, destEnd, allocator); while (toEnd != destBegin) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, --destBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03)); endGuard.moveBegin(-1); } endGuard.release(); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 3 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 4 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04> void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); size_type numElements = 1; size_type tailLen = toEnd - toBegin; size_type numGuarded = tailLen < numElements ? tailLen : numElements; TARGET_TYPE *destBegin = toBegin + numElements; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) { std::memmove((void *)destBegin, toBegin, tailLen * sizeof(TARGET_TYPE)); } TARGET_TYPE *destEnd = toEnd + numElements; AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, destEnd - numGuarded, destEnd - numGuarded, destEnd, allocator); while (guard.middle() != guard.end()) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, guard.destination(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04)); guard.advance(); } if (tailLen < numElements) { AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin, destEnd, allocator); while (toEnd != destBegin) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, --destBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04)); endGuard.moveBegin(-1); } endGuard.release(); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 4 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 5 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05> void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); size_type numElements = 1; size_type tailLen = toEnd - toBegin; size_type numGuarded = tailLen < numElements ? tailLen : numElements; TARGET_TYPE *destBegin = toBegin + numElements; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) { std::memmove((void *)destBegin, toBegin, tailLen * sizeof(TARGET_TYPE)); } TARGET_TYPE *destEnd = toEnd + numElements; AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, destEnd - numGuarded, destEnd - numGuarded, destEnd, allocator); while (guard.middle() != guard.end()) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, guard.destination(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05)); guard.advance(); } if (tailLen < numElements) { AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin, destEnd, allocator); while (toEnd != destBegin) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, --destBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05)); endGuard.moveBegin(-1); } endGuard.release(); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 5 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 6 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06> void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); size_type numElements = 1; size_type tailLen = toEnd - toBegin; size_type numGuarded = tailLen < numElements ? tailLen : numElements; TARGET_TYPE *destBegin = toBegin + numElements; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) { std::memmove((void *)destBegin, toBegin, tailLen * sizeof(TARGET_TYPE)); } TARGET_TYPE *destEnd = toEnd + numElements; AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, destEnd - numGuarded, destEnd - numGuarded, destEnd, allocator); while (guard.middle() != guard.end()) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, guard.destination(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06)); guard.advance(); } if (tailLen < numElements) { AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin, destEnd, allocator); while (toEnd != destBegin) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, --destBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06)); endGuard.moveBegin(-1); } endGuard.release(); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 6 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 7 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07> void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); size_type numElements = 1; size_type tailLen = toEnd - toBegin; size_type numGuarded = tailLen < numElements ? tailLen : numElements; TARGET_TYPE *destBegin = toBegin + numElements; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) { std::memmove((void *)destBegin, toBegin, tailLen * sizeof(TARGET_TYPE)); } TARGET_TYPE *destEnd = toEnd + numElements; AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, destEnd - numGuarded, destEnd - numGuarded, destEnd, allocator); while (guard.middle() != guard.end()) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, guard.destination(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07)); guard.advance(); } if (tailLen < numElements) { AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin, destEnd, allocator); while (toEnd != destBegin) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, --destBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07)); endGuard.moveBegin(-1); } endGuard.release(); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 7 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 8 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08> void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); size_type numElements = 1; size_type tailLen = toEnd - toBegin; size_type numGuarded = tailLen < numElements ? tailLen : numElements; TARGET_TYPE *destBegin = toBegin + numElements; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) { std::memmove((void *)destBegin, toBegin, tailLen * sizeof(TARGET_TYPE)); } TARGET_TYPE *destEnd = toEnd + numElements; AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, destEnd - numGuarded, destEnd - numGuarded, destEnd, allocator); while (guard.middle() != guard.end()) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, guard.destination(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08)); guard.advance(); } if (tailLen < numElements) { AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin, destEnd, allocator); while (toEnd != destBegin) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, --destBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08)); endGuard.moveBegin(-1); } endGuard.release(); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 8 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 9 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09> void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); size_type numElements = 1; size_type tailLen = toEnd - toBegin; size_type numGuarded = tailLen < numElements ? tailLen : numElements; TARGET_TYPE *destBegin = toBegin + numElements; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) { std::memmove((void *)destBegin, toBegin, tailLen * sizeof(TARGET_TYPE)); } TARGET_TYPE *destEnd = toEnd + numElements; AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, destEnd - numGuarded, destEnd - numGuarded, destEnd, allocator); while (guard.middle() != guard.end()) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, guard.destination(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09)); guard.advance(); } if (tailLen < numElements) { AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin, destEnd, allocator); while (toEnd != destBegin) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, --destBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09)); endGuard.moveBegin(-1); } endGuard.release(); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 9 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 10 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09, class ARGS_10> void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); size_type numElements = 1; size_type tailLen = toEnd - toBegin; size_type numGuarded = tailLen < numElements ? tailLen : numElements; TARGET_TYPE *destBegin = toBegin + numElements; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) { std::memmove((void *)destBegin, toBegin, tailLen * sizeof(TARGET_TYPE)); } TARGET_TYPE *destEnd = toEnd + numElements; AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, destEnd - numGuarded, destEnd - numGuarded, destEnd, allocator); while (guard.middle() != guard.end()) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, guard.destination(), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09), BSLS_COMPILERFEATURES_FORWARD(ARGS_10, args_10)); guard.advance(); } if (tailLen < numElements) { AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin, destEnd, allocator); while (toEnd != destBegin) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, --destBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS_01,args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02,args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03,args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04,args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05,args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06,args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07,args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08,args_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09,args_09), BSLS_COMPILERFEATURES_FORWARD(ARGS_10,args_10)); endGuard.moveBegin(-1); } endGuard.release(); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 10 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 0 template <class TARGET_TYPE, class ALLOCATOR> void ArrayPrimitives_Imp::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (toEnd > toBegin) { bsls::ObjectBuffer<TARGET_TYPE> space; bsl::allocator_traits<ALLOCATOR>::construct( allocator, BSLS_UTIL_ADDRESSOF(space.object())); bslma::DestructorProctor<TARGET_TYPE> temp( BSLS_UTIL_ADDRESSOF(space.object())); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1))); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd, toEnd + 1, allocator); TARGET_TYPE *destEnd = toEnd; TARGET_TYPE *srcEnd = toEnd - 1; while (toBegin != srcEnd) { *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd); } *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object()); guard.release(); } else { bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 0 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 1 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01> void ArrayPrimitives_Imp::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (toEnd > toBegin) { bsls::ObjectBuffer<TARGET_TYPE> space; bsl::allocator_traits<ALLOCATOR>::construct( allocator, BSLS_UTIL_ADDRESSOF(space.object()), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01)); bslma::DestructorProctor<TARGET_TYPE> temp( BSLS_UTIL_ADDRESSOF(space.object())); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1))); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd, toEnd + 1, allocator); TARGET_TYPE *destEnd = toEnd; TARGET_TYPE *srcEnd = toEnd - 1; while (toBegin != srcEnd) { *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd); } *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object()); guard.release(); } else { bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01)); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 1 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 2 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02> void ArrayPrimitives_Imp::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (toEnd > toBegin) { bsls::ObjectBuffer<TARGET_TYPE> space; bsl::allocator_traits<ALLOCATOR>::construct( allocator, BSLS_UTIL_ADDRESSOF(space.object()), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02)); bslma::DestructorProctor<TARGET_TYPE> temp( BSLS_UTIL_ADDRESSOF(space.object())); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1))); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd, toEnd + 1, allocator); TARGET_TYPE *destEnd = toEnd; TARGET_TYPE *srcEnd = toEnd - 1; while (toBegin != srcEnd) { *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd); } *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object()); guard.release(); } else { bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02)); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 2 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 3 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03> void ArrayPrimitives_Imp::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (toEnd > toBegin) { bsls::ObjectBuffer<TARGET_TYPE> space; bsl::allocator_traits<ALLOCATOR>::construct( allocator, BSLS_UTIL_ADDRESSOF(space.object()), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03)); bslma::DestructorProctor<TARGET_TYPE> temp( BSLS_UTIL_ADDRESSOF(space.object())); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1))); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd, toEnd + 1, allocator); TARGET_TYPE *destEnd = toEnd; TARGET_TYPE *srcEnd = toEnd - 1; while (toBegin != srcEnd) { *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd); } *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object()); guard.release(); } else { bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03)); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 3 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 4 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04> void ArrayPrimitives_Imp::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (toEnd > toBegin) { bsls::ObjectBuffer<TARGET_TYPE> space; bsl::allocator_traits<ALLOCATOR>::construct( allocator, BSLS_UTIL_ADDRESSOF(space.object()), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04)); bslma::DestructorProctor<TARGET_TYPE> temp( BSLS_UTIL_ADDRESSOF(space.object())); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1))); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd, toEnd + 1, allocator); TARGET_TYPE *destEnd = toEnd; TARGET_TYPE *srcEnd = toEnd - 1; while (toBegin != srcEnd) { *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd); } *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object()); guard.release(); } else { bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04)); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 4 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 5 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05> void ArrayPrimitives_Imp::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (toEnd > toBegin) { bsls::ObjectBuffer<TARGET_TYPE> space; bsl::allocator_traits<ALLOCATOR>::construct( allocator, BSLS_UTIL_ADDRESSOF(space.object()), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05)); bslma::DestructorProctor<TARGET_TYPE> temp( BSLS_UTIL_ADDRESSOF(space.object())); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1))); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd, toEnd + 1, allocator); TARGET_TYPE *destEnd = toEnd; TARGET_TYPE *srcEnd = toEnd - 1; while (toBegin != srcEnd) { *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd); } *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object()); guard.release(); } else { bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05)); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 5 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 6 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06> void ArrayPrimitives_Imp::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (toEnd > toBegin) { bsls::ObjectBuffer<TARGET_TYPE> space; bsl::allocator_traits<ALLOCATOR>::construct( allocator, BSLS_UTIL_ADDRESSOF(space.object()), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06)); bslma::DestructorProctor<TARGET_TYPE> temp( BSLS_UTIL_ADDRESSOF(space.object())); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1))); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd, toEnd + 1, allocator); TARGET_TYPE *destEnd = toEnd; TARGET_TYPE *srcEnd = toEnd - 1; while (toBegin != srcEnd) { *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd); } *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object()); guard.release(); } else { bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06)); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 6 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 7 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07> void ArrayPrimitives_Imp::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (toEnd > toBegin) { bsls::ObjectBuffer<TARGET_TYPE> space; bsl::allocator_traits<ALLOCATOR>::construct( allocator, BSLS_UTIL_ADDRESSOF(space.object()), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07)); bslma::DestructorProctor<TARGET_TYPE> temp( BSLS_UTIL_ADDRESSOF(space.object())); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1))); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd, toEnd + 1, allocator); TARGET_TYPE *destEnd = toEnd; TARGET_TYPE *srcEnd = toEnd - 1; while (toBegin != srcEnd) { *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd); } *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object()); guard.release(); } else { bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07)); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 7 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 8 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08> void ArrayPrimitives_Imp::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (toEnd > toBegin) { bsls::ObjectBuffer<TARGET_TYPE> space; bsl::allocator_traits<ALLOCATOR>::construct( allocator, BSLS_UTIL_ADDRESSOF(space.object()), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08)); bslma::DestructorProctor<TARGET_TYPE> temp( BSLS_UTIL_ADDRESSOF(space.object())); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1))); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd, toEnd + 1, allocator); TARGET_TYPE *destEnd = toEnd; TARGET_TYPE *srcEnd = toEnd - 1; while (toBegin != srcEnd) { *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd); } *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object()); guard.release(); } else { bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08)); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 8 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 9 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09> void ArrayPrimitives_Imp::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (toEnd > toBegin) { bsls::ObjectBuffer<TARGET_TYPE> space; bsl::allocator_traits<ALLOCATOR>::construct( allocator, BSLS_UTIL_ADDRESSOF(space.object()), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09)); bslma::DestructorProctor<TARGET_TYPE> temp( BSLS_UTIL_ADDRESSOF(space.object())); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1))); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd, toEnd + 1, allocator); TARGET_TYPE *destEnd = toEnd; TARGET_TYPE *srcEnd = toEnd - 1; while (toBegin != srcEnd) { *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd); } *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object()); guard.release(); } else { bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09)); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 9 #if BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 10 template <class TARGET_TYPE, class ALLOCATOR, class ARGS_01, class ARGS_02, class ARGS_03, class ARGS_04, class ARGS_05, class ARGS_06, class ARGS_07, class ARGS_08, class ARGS_09, class ARGS_10> void ArrayPrimitives_Imp::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_01) args_01, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_02) args_02, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_03) args_03, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_04) args_04, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_05) args_05, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_06) args_06, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_07) args_07, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_08) args_08, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_09) args_09, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS_10) args_10) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (toEnd > toBegin) { bsls::ObjectBuffer<TARGET_TYPE> space; bsl::allocator_traits<ALLOCATOR>::construct( allocator, BSLS_UTIL_ADDRESSOF(space.object()), BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09), BSLS_COMPILERFEATURES_FORWARD(ARGS_10, args_10)); bslma::DestructorProctor<TARGET_TYPE> temp( BSLS_UTIL_ADDRESSOF(space.object())); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1))); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd, toEnd + 1, allocator); TARGET_TYPE *destEnd = toEnd; TARGET_TYPE *srcEnd = toEnd - 1; while (toBegin != srcEnd) { *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd); } *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object()); guard.release(); } else { bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, BSLS_COMPILERFEATURES_FORWARD(ARGS_01, args_01), BSLS_COMPILERFEATURES_FORWARD(ARGS_02, args_02), BSLS_COMPILERFEATURES_FORWARD(ARGS_03, args_03), BSLS_COMPILERFEATURES_FORWARD(ARGS_04, args_04), BSLS_COMPILERFEATURES_FORWARD(ARGS_05, args_05), BSLS_COMPILERFEATURES_FORWARD(ARGS_06, args_06), BSLS_COMPILERFEATURES_FORWARD(ARGS_07, args_07), BSLS_COMPILERFEATURES_FORWARD(ARGS_08, args_08), BSLS_COMPILERFEATURES_FORWARD(ARGS_09, args_09), BSLS_COMPILERFEATURES_FORWARD(ARGS_10, args_10)); } } #endif // BSLALG_ARRAYPRIMITIVES_VARIADIC_LIMIT_F >= 10 #else // The generated code below is a workaround for the absence of perfect // forwarding in some compilers. template <class TARGET_TYPE, class ALLOCATOR, class... ARGS> inline void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args) { ArrayPrimitives_Imp::emplace(toBegin, toEnd, allocator, (bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS>*)0, BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...); } template <class TARGET_TYPE, class ALLOCATOR, class... ARGS> void ArrayPrimitives_Imp::emplace( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); size_type numElements = 1; size_type tailLen = toEnd - toBegin; size_type numGuarded = tailLen < numElements ? tailLen : numElements; TARGET_TYPE *destBegin = toBegin + numElements; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) { std::memmove((void *)destBegin, toBegin, tailLen * sizeof(TARGET_TYPE)); } TARGET_TYPE *destEnd = toEnd + numElements; AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, destEnd - numGuarded, destEnd - numGuarded, destEnd, allocator); while (guard.middle() != guard.end()) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, guard.destination(), BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...); guard.advance(); } if (tailLen < numElements) { AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin, destEnd, allocator); while (toEnd != destBegin) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, --destBegin, BSLS_COMPILERFEATURES_FORWARD(ARGS,args)...); endGuard.moveBegin(-1); } endGuard.release(); } } template <class TARGET_TYPE, class ALLOCATOR, class... ARGS> void ArrayPrimitives_Imp::emplace(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *, BSLS_COMPILERFEATURES_FORWARD_REF(ARGS)... args) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (toEnd > toBegin) { bsls::ObjectBuffer<TARGET_TYPE> space; bsl::allocator_traits<ALLOCATOR>::construct( allocator, BSLS_UTIL_ADDRESSOF(space.object()), BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...); bslma::DestructorProctor<TARGET_TYPE> temp( BSLS_UTIL_ADDRESSOF(space.object())); bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, bslmf::MovableRefUtil::move_if_noexcept(*(toEnd - 1))); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd, toEnd + 1, allocator); TARGET_TYPE *destEnd = toEnd; TARGET_TYPE *srcEnd = toEnd - 1; while (toBegin != srcEnd) { *--destEnd = bslmf::MovableRefUtil::move_if_noexcept(*--srcEnd); } *toBegin = bslmf::MovableRefUtil::move_if_noexcept(space.object()); guard.release(); } else { bsl::allocator_traits<ALLOCATOR>::construct( allocator, toEnd, BSLS_COMPILERFEATURES_FORWARD(ARGS, args)...); } } // }}} END GENERATED CODE #endif // *** 'erase' overloads: *** template <class TARGET_TYPE, class ALLOCATOR> void ArrayPrimitives_Imp::erase( TARGET_TYPE *first, TARGET_TYPE *middle, TARGET_TYPE *last, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(first, middle)); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(middle, last)); // Key to the transformation diagrams: //.. // t...z Original contents of '[first, middle)' // A...G Original contents of '[middle, last)' // _ Destroyed array element //.. //.. // Transformation: tuvABCDEFG => ___ABCDEFG (no throw) //.. ArrayDestructionPrimitives::destroy(first, middle, allocator); //.. // Transformation: ___ABCDEFG => ABCDEFG___ (might overlap, but no throw) //.. size_type numBytes = reinterpret_cast<const char *>(last) - reinterpret_cast<const char *>(middle); if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numBytes != 0)) { std::memmove((void *)first, middle, numBytes); } } template <class TARGET_TYPE, class ALLOCATOR> void ArrayPrimitives_Imp::erase(TARGET_TYPE *first, TARGET_TYPE *middle, TARGET_TYPE *last, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(first, middle)); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(middle, last)); // Key to the transformation diagrams: //.. // t...z Original contents of '[first, middle)' // A...G Original contents of '[middle, last)' // _ Destructed array element //.. //.. // Transformation: tuvABCDEFG => ABCDEFGEFG. //.. while (middle != last) { *first++ = bslmf::MovableRefUtil::move_if_noexcept(*middle++); } //.. // Transformation: ABCDEFGEFG => ABCDEFG___. //.. ArrayDestructionPrimitives::destroy(first, middle, allocator); } // *** 'insert' with 'value' overloads: *** template <class TARGET_TYPE, class ALLOCATOR> inline void ArrayPrimitives_Imp::insert( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, const TARGET_TYPE& value, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); // Key to the transformation diagrams: //.. // A...G original contents of '[toBegin, toEnd)' ("tail") // v...v contents of '[fromBegin, fromEnd)' ("input") // _____ uninitialized array element //.. // ALIASING: If 'value' is a reference into the array 'toBegin..toEnd', // then moving the array first might introduce a change in 'value'. Since // type is bitwise copyable, then no memory changes outside the array, so // the test below is sufficient to discover all the possible aliasing. // Note that we never make a copy. const TARGET_TYPE *tempValuePtr = BSLS_UTIL_ADDRESSOF(value); if (toBegin <= tempValuePtr && tempValuePtr < toEnd ) { // Adjust pointer for shifting after the move. tempValuePtr += numElements; } //.. // Transformation: ABCDE___ => ___ABCDE (might overlap). //.. const size_type numBytes = reinterpret_cast<const char*>(toEnd) - reinterpret_cast<const char*>(toBegin); if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numBytes != 0)) { std::memmove((void *)(toBegin + numElements), toBegin, numBytes); } //.. // Transformation: ___ABCDE => v__ABCDE (no overlap). //.. // Use 'copyConstruct' instead of 'memcpy' because the former optimizes for // fundamental types using 'operator=' instead, which avoid the 'memcpy' // function call. bsl::allocator_traits<ALLOCATOR>::construct(allocator, toBegin, *tempValuePtr); //.. // Transformation: v__ABCDE => vvvABCDE. //.. bitwiseFillN(reinterpret_cast<char *>(toBegin), sizeof value, numElements * sizeof value); } template <class TARGET_TYPE, class ALLOCATOR> void ArrayPrimitives_Imp::insert( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, const TARGET_TYPE& value, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); // Key to the transformation diagrams: //.. // A...G original contents of '[toBegin, toEnd)' ("tail") // v...v contents of '[fromBegin, fromEnd)' ("input") // _____ uninitialized array element // [...] part of an array guarded by an exception guard object // |.(.,.) part of array guarded by move guard // (middle indicated by ',' and dest by '|') //.. const TARGET_TYPE *tempValuePtr = BSLS_UTIL_ADDRESSOF(value); if (toBegin <= tempValuePtr && tempValuePtr < toEnd + numElements) { // Adjust pointer for shifting after the move. tempValuePtr += numElements; } size_type tailLen = toEnd - toBegin; size_type numGuarded = tailLen < numElements ? tailLen : numElements; //.. // Transformation: ABCDE_______ => _______ABCDE (might overlap) //.. TARGET_TYPE *destBegin = toBegin + numElements; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) { std::memmove((void *)destBegin, toBegin, tailLen * sizeof(TARGET_TYPE)); } //.. // Transformation: |_______(,ABCDE) => vvvvv|__(ABCDE,) //.. TARGET_TYPE *destEnd = toEnd + numElements; AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, destEnd - numGuarded, destEnd - numGuarded, destEnd, allocator); while (guard.middle() != guard.end()) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, guard.destination(), *tempValuePtr); guard.advance(); } // The bitwise 'guard' is now inactive, since 'middle() == end()' and // 'guard.destination()' is the smaller of 'destBegin' or 'toEnd'. if (tailLen < numElements) { // There still is a gap of 'numElements - tailLen' to fill in between // 'toEnd' and 'destBegin'. The elements that have been 'memmove'-ed // need to be guarded, we fill the gap backward from there to keep // guarded portion in one piece. AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard(destBegin, destEnd, allocator); //.. // Transformation: vvvvv__[ABCDE] => vvvvv[vvABCDE] //.. while (toEnd != destBegin) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, --destBegin, *tempValuePtr); endGuard.moveBegin(-1); } endGuard.release(); } } template <class TARGET_TYPE, class ALLOCATOR> void ArrayPrimitives_Imp::insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, const TARGET_TYPE& value, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); // Aliasing: Make a temp copy of 'value' (always). The reason is that // 'value' could be a reference inside the input range, or even outside // but with lifetime controlled by one of these values, and so the next // transformation could invalidate 'value'. Note: One cannot rely on // 'TARGET_TYPE' to have a single-argument copy constructor (i.e., // default allocator argument to 0) if it takes an allocator; hence the // constructor proxy. bsls::ObjectBuffer<TARGET_TYPE> space; bslma::ConstructionUtil::construct(BSLS_UTIL_ADDRESSOF(space.object()), bslma::Default::allocator(), value); bslma::DestructorProctor<TARGET_TYPE> temp( BSLS_UTIL_ADDRESSOF(space.object())); // Key to the transformation diagrams: //.. // A...G original contents of '[toBegin, toEnd)' ("tail") // v...v copies of 'value' ("input") // _____ uninitialized array elements // [...] part of array protected by an exception guard object //.. const size_type tailLen = toEnd - toBegin; if (tailLen >= numElements) { // Tail is not shorter than input. //.. // Transformation: ABCDEFG___[] => ABCDEFG[EFG]. //.. moveIfNoexcept(toEnd, // destination toEnd - numElements, // source toEnd, // end source allocator, (bslmf::MetaInt<e_NIL_TRAITS> *)0); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd, toEnd + numElements, allocator); // TBD: this does the same thing as the old code - don't like that we // circumvent the whole allocator thing, but for now, let's keep it // consistent. // ConstructorProxy<TARGET_TYPE> // tempValue(value, bslma::Default::allocator()); //.. // Transformation: ABCDEFG[EFG] => ABCABCD[EFG]. //.. TARGET_TYPE *src = toEnd - numElements; TARGET_TYPE *dest = toEnd; while (toBegin != src) { *--dest = bslmf::MovableRefUtil::move_if_noexcept(*--src); } //.. // Transformation: ABCABCD[EFG] => vvvABCD[EFG]. //.. for ( ; toBegin != dest; ++toBegin) { *toBegin = space.object(); } // TBD: this can't be good guard.release(); } else { // Tail is shorter than input. We can avoid the temp copy of value // since there will be space to make a first copy after the tail, and // use that to make the subsequent copies. // // TBD: Update comment now that the assumption is no longer true, and // we make a copy at the top of the call, regardless. We could // restore this optimization if we use metaprogramming to check if // 'moveIfNoexcept' will move or copy, but not convinced it is worth // the complexity. difference_type remElements = numElements - tailLen; //.. // Transformation: ABC_______[] => ABC____[ABC]. //.. moveIfNoexcept(toBegin + numElements, // destination toBegin, // source toEnd, // end source allocator, (bslmf::MetaInt<e_NIL_TRAITS>*)0); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd + remElements, toEnd + numElements, allocator); //.. // Transformation: ABC____[ABC] => ABC[vvvvABC]. //.. uninitializedFillN(toEnd, space.object(), remElements, &allocator, (bslmf::MetaInt<e_NIL_TRAITS>*)0); guard.moveBegin(-remElements); //.. // Transformation: ABC[vvvvABC] => vvv[vvvvABC]. //.. for ( ; toBegin != toEnd; ++toBegin) { *toBegin = space.object(); } guard.release(); } } // *** 'insert' with 'FWD_ITER' overloads: *** template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR> inline void ArrayPrimitives_Imp::insert( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, FWD_ITER fromBegin, FWD_ITER fromEnd, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_IS_POINTER_TO_POINTER> *) { // We may be casting a function pointer to a 'void *' here, so this won't // work if we port to an architecture where the two are of different sizes. BSLMF_ASSERT(sizeof(void *) == sizeof(void (*)())); #if defined(BSLALG_ARRAYPRIMITIVES_CANNOT_REMOVE_POINTER_FROM_FUNCTION_POINTER) // fall back on traditional C-style casts. insert((void * *)toBegin, (void * *)toEnd, (void * const *)fromBegin, (void * const *)fromEnd, numElements, allocator, (bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *) 0); #else typedef typename bsl::remove_cv< typename bsl::remove_pointer<TARGET_TYPE>::type>::type NcPtrType; typedef typename bsl::remove_cv< typename bsl::remove_pointer< typename bsl::remove_pointer<FWD_ITER>::type>::type>::type NcIter; insert( reinterpret_cast<void * *>(const_cast<NcPtrType **>(toBegin)), reinterpret_cast<void * *>(const_cast<NcPtrType **>(toEnd)), reinterpret_cast<void * const *>(const_cast<NcIter * const *>(fromBegin)), reinterpret_cast<void * const *>(const_cast<NcIter * const *>(fromEnd)), numElements, allocator, (bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *) 0); #endif } template <class TARGET_TYPE, class ALLOCATOR> inline void ArrayPrimitives_Imp::insert( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, const TARGET_TYPE *fromBegin, const TARGET_TYPE *fromEnd, size_type numElements, ALLOCATOR , bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *) { BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); // 'FWD_ITER' has been converted to a 'const TARGET_TYPE *' and // 'TARGET_TYPE' is bit-wise copyable. BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(fromBegin, fromEnd)); BSLS_ASSERT_SAFE(fromBegin || 0 == numElements); BSLS_ASSERT_SAFE(fromBegin + numElements == fromEnd); BSLS_ASSERT_SAFE(fromEnd <= toBegin || toEnd + numElements <= fromBegin); (void) fromEnd; // quell warning when 'BSLS_ASSERT_SAFE' is compiled out // Key to the transformation diagrams: //.. // A...G original contents of '[toBegin, toEnd)' ("tail") // t...z contents of '[fromBegin, fromEnd)' ("input") // _____ uninitialized array element //.. //.. // Transformation: ABCDE_______ => _______ABCDE (might overlap). //.. const size_type numBytes = reinterpret_cast<const char*>(toEnd) - reinterpret_cast<const char*>(toBegin); if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numBytes != 0)) { std::memmove((void *)(toBegin + numElements), toBegin, numBytes); } //.. // Transformation: _______ABCDE => tuvwxyzABCDE (no overlap). //.. if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(numElements != 0)) { std::memcpy((void *)toBegin, fromBegin, numElements * sizeof(TARGET_TYPE)); } } template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR> void ArrayPrimitives_Imp::insert( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, FWD_ITER fromBegin, FWD_ITER, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *) { // 'TARGET_TYPE' is bit-wise moveable. BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (0 == numElements) { return; // RETURN } // The following assertions make sense only if 'FWD_ITER' is a pointer to a // possibly cv-qualified 'TARGET_TYPE', and are tested in that overload // (see above). //.. // BSLS_ASSERT(fromBegin + numElements == fromEnd); // BSLS_ASSERT(fromEnd <= toBegin || toEnd + numElements <= fromBegin); //.. // Key to the transformation diagrams: //.. // A...G original contents of '[toBegin, toEnd)' ("tail") // t...z contents of '[fromBegin, fromEnd)' ("input") // _____ uninitialized array element // [...] part of array guarded by exception guard // |.(.,.) part of array guarded by move guard // (middle indicated by ',' and dest by '|') //.. const size_type tailLen = toEnd - toBegin; const size_type numGuarded = tailLen < numElements ? tailLen : numElements; //.. // Transformation: ABCDE____ => ____ABCDE (might overlap). //.. TARGET_TYPE *destBegin = toBegin + numElements; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) { std::memmove((void *)destBegin, toBegin, tailLen * sizeof(TARGET_TYPE)); } //.. // Transformation: |_______(,ABCDE) => tuvwx|__(ABCDE,). //.. TARGET_TYPE *destEnd = toEnd + numElements; AutoArrayMoveDestructor<TARGET_TYPE, ALLOCATOR> guard(toBegin, destEnd - numGuarded, destEnd - numGuarded, destEnd, allocator); for (; guard.middle() != guard.end(); ++fromBegin) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, guard.destination(), *fromBegin); guard.advance(); } // The bitwise 'guard' is now inactive, since 'middle() == end()', and // 'guard.destination()' is the smaller of 'destBegin' or 'toEnd'. if (tailLen < numElements) { // There still is a gap of 'numElements - tailLen' to fill in between // 'toEnd' and 'destBegin'. The elements that have been 'memmove'-ed // need to be guarded, and we need to continue to fill the hole at the // same guarding the copied elements as well. AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard1(toEnd, toEnd, allocator); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> endGuard2(destBegin, destEnd, allocator); //.. // Transformation: tuvwx[]__[ABCDE] => tuvwx[yz][ABCDE]. //.. for (; toEnd != destBegin; ++fromBegin) { bsl::allocator_traits<ALLOCATOR>::construct(allocator, toEnd, *fromBegin); toEnd = endGuard1.moveEnd(1); } endGuard1.release(); endGuard2.release(); } } template <class TARGET_TYPE, class FWD_ITER, class ALLOCATOR> void ArrayPrimitives_Imp::insert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, FWD_ITER fromBegin, FWD_ITER fromEnd, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (0 == numElements) { return; // RETURN } // Key to the transformation diagrams: //.. // A...G original contents of '[toBegin, toEnd)' ("tail") // t...z contents of '[fromBegin, fromEnd)' ("input") // _____ uninitialized array elements // [...] part of array protected by a guard object //.. const size_type tailLen = toEnd - toBegin; if (tailLen > numElements) { // Tail is longer than input. //.. // Transformation: ABCDEFG___[] => ABCDEFG[EFG]. //.. moveIfNoexcept(toEnd, // destination toEnd - numElements, // source toEnd, // end source allocator, (bslmf::MetaInt<e_NIL_TRAITS>*)0); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd, toEnd + numElements, allocator); //.. // Transformation: ABCDEFG[EFG] => ABCABCD[EFG]. //.. TARGET_TYPE *src = toEnd - numElements; TARGET_TYPE *dest = toEnd; while (toBegin != src) { *--dest = bslmf::MovableRefUtil::move_if_noexcept(*--src); } //.. // Transformation: ABCABCD[EFG] => tuvABCD[EFG]. //.. for (; toBegin != dest; ++toBegin, ++fromBegin) { *toBegin = *fromBegin; } guard.release(); } else { // Tail is not longer than input (numElements). difference_type remElements = numElements - tailLen; //.. // Transformation: ABC_______[] => ABC____[ABC] //.. moveIfNoexcept(toBegin + numElements, // destination toBegin, // source toEnd, // end source allocator, (bslmf::MetaInt<e_NIL_TRAITS>*)0); AutoArrayDestructor<TARGET_TYPE, ALLOCATOR> guard(toEnd + remElements, toEnd + numElements, allocator); //.. // Transformation: ABC____[ABC] => tuv____[ABC]. //.. for (; toBegin != toEnd; ++fromBegin, ++toBegin) { *toBegin = *fromBegin; } //.. // Transformation: tuv____[ABC] => tuvwxyzABC[]. //.. copyConstruct(toBegin, fromBegin, fromEnd, allocator, (bslmf::MetaInt<e_NIL_TRAITS>*)0); guard.release(); } } template <class FWD_ITER, class ALLOCATOR> void ArrayPrimitives_Imp::insert( void **toBegin, void **toEnd, FWD_ITER fromBegin, FWD_ITER, size_type numElements, ALLOCATOR , bslmf::MetaInt<e_IS_ITERATOR_TO_FUNCTION_POINTER> *) { // This very specific overload is required for the case that 'FWD_ITER' is // an iterator that is not a pointer, iterating over a sequence of function // pointers. The implementation relies on the conditionally-supported // behavior that any function pointer can be 'reinterpret_cast' to // 'void *'. // 'TARGET_TYPE' is bit-wise moveable. BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); if (0 == numElements) { return; // RETURN } // The following assertions make sense only if 'FWD_ITER' is a pointer to a // possibly cv-qualified 'TARGET_TYPE', and are tested in that overload // (see above). //.. // BSLS_ASSERT(fromBegin + numElements == fromEnd); // BSLS_ASSERT(fromEnd <= toBegin || toEnd + numElements <= fromBegin); //.. // Key to the transformation diagrams: //.. // A...G original contents of '[toBegin, toEnd)' ("tail") // t...z contents of '[fromBegin, fromEnd)' ("input") // _____ uninitialized array element // [...] part of array guarded by exception guard // |.(.,.) part of array guarded by move guard // (middle indicated by ',' and dest by '|') //.. const size_type tailLen = toEnd - toBegin; //.. // Transformation: ABCDE____ => ____ABCDE (might overlap). //.. void **destBegin = toBegin + numElements; if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY(tailLen != 0)) { std::memmove(destBegin, toBegin, tailLen * sizeof(void **)); } for (size_type i = 0; i < numElements; ++i) { *toBegin = reinterpret_cast<void *>(*fromBegin); ++fromBegin; ++toBegin; } } // *** 'moveInsert' overloads: *** template <class TARGET_TYPE, class ALLOCATOR> inline void ArrayPrimitives_Imp::moveInsert( TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, TARGET_TYPE **lastPtr, TARGET_TYPE *first, TARGET_TYPE *last, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(first, last)); BSLS_ASSERT_SAFE(first || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); BSLS_ASSERT_SAFE(lastPtr); // Functionally indistinguishable from this: *lastPtr = last; insert(toBegin, toEnd, first, last, numElements, allocator, (bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS>*)0); *lastPtr = first; } template <class TARGET_TYPE, class ALLOCATOR> inline void ArrayPrimitives_Imp::moveInsert(TARGET_TYPE *toBegin, TARGET_TYPE *toEnd, TARGET_TYPE **lastPtr, TARGET_TYPE *first, TARGET_TYPE *last, size_type numElements, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(toBegin, toEnd)); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(first, last)); BSLS_ASSERT_SAFE(first || 0 == numElements); BSLMF_ASSERT((bsl::is_same<size_type, std::size_t>::value)); BSLS_ASSERT_SAFE(lastPtr); // There isn't any advantage at destroying [first,last) one by one as we're // moving it, except perhaps for slightly better memory usage. *lastPtr = last; insert(toBegin, toEnd, first, last, numElements, allocator, (bslmf::MetaInt<e_NIL_TRAITS>*)0); ArrayDestructionPrimitives::destroy(first, last, allocator); *lastPtr = first; } // *** 'rotate' overloads: *** template <class TARGET_TYPE> inline void ArrayPrimitives_Imp::rotate( TARGET_TYPE *begin, TARGET_TYPE *middle, TARGET_TYPE *end, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(begin, middle)); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(middle, end)); bitwiseRotate(reinterpret_cast<char *>(begin), reinterpret_cast<char *>(middle), reinterpret_cast<char *>(end)); } template <class TARGET_TYPE> void ArrayPrimitives_Imp::rotate(TARGET_TYPE *begin, TARGET_TYPE *middle, TARGET_TYPE *end, bslmf::MetaInt<e_NIL_TRAITS> *) { BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(begin, middle)); BSLS_ASSERT_SAFE(!ArrayPrimitives_Imp::isInvalidRange(middle, end)); if (begin == middle || middle == end) { // This test changes into O(1) what would otherwise be O(N): Do not // remove! return; // RETURN } // This case is simple enough, it should be taken care of on its own. const std::size_t numElements = middle - begin; const std::size_t remElements = end - middle; if (numElements == remElements) { for (; middle != end; ++begin, ++middle) { TARGET_TYPE tmp(*middle); *middle = *begin; *begin = tmp; } return; // RETURN } // This algorithm proceeds by decomposing the rotation into cycles, which // can then be rotated using a single element buffer. First we compute the // 'gcd(end - begin, numElements)' which is the number of cycles in the // rotation. std::size_t numCycles = end - begin; std::size_t remainder = numElements; while (remainder != 0) { std::size_t t = numCycles % remainder; numCycles = remainder; remainder = t; } // Key to the transformation diagrams: //.. // A...D Contents of the current cycle // W...Z Contents of another cycle // _ Elements not in the current cycle //.. for (std::size_t i = 0; i < numCycles; ++i) { // Let the current cycle be initially 'A__B__C__D__', (note that its // stride is 'length / numCycles') and let (*) denote the current // position of 'ptr'. TARGET_TYPE *ptr = begin; // seed for current cycle: A(*)__B__C__D__ TARGET_TYPE tmp = *ptr; // value held at the seed: tmp == A if (numElements < remElements) { // Rotate the cycle forward by numElements positions (or backward // by -(length-numElements)=-remElements positions if crossing the // boundary forward). The transformation is: //.. // A(*)__B__C__D__ => B__B(*)__C__D__ // => B__C__C(*)__D__ // => B__C__D__D(*)__ //.. // The length of the cycle is always 'length / numCycles', but it // crosses the range boundaries 'numElements / numCycles' times, // each triggering an extra assignment in the 'if' clause below, so // the loop must only be executed: //.. // (length - numElements) / numCycles = remElements / numCycles //.. // times. std::size_t cycleSize = remElements / numCycles; for (std::size_t j = 0; j < cycleSize; ++j) { if (ptr > begin + remElements) { // Wrap around the range boundaries. (Note that // '-remElements == numElements - (end - begin)'.) *ptr = *(ptr - remElements); ptr -= remElements; } *ptr = *(ptr + numElements); ptr += numElements; } } else { // Rotate the cycle backward by '-remElements' positions (or // forward by 'numElements' positions if crossing the boundary // backward). The transformation is: //.. // A(*)__B__C__D__ => D__B__C__D(*)__ // => D__B__C(*)__C__ // => D__B(*)__B__C__ //.. // The length of the cycle is always 'length/numCycles', but going // backward (which adds an initial extra crossing) crosses the // range boundaries 'remElements/numCycles+1' times each of which // trigger an extra assignment in the 'if' clause below, so the // loop must only be executed: //.. // (length - remElements) / numCycles - 1 = // numElements / numCycles - 1 //.. // times. std::size_t cycleSize = numElements / numCycles - 1; for (std::size_t j = 0; j < cycleSize; ++j) { if (ptr < end - numElements) { *ptr = *(ptr + numElements); ptr += numElements; } *ptr = *(ptr - remElements); ptr -= remElements; } } *ptr = tmp; // Close the cycle, e.g.: //.. // (first case): B__C__D__D(*)__ => B__C__D__A__ // (second case): D__D(*)__B__C__ => D__A__B__C__ //.. ++begin; // and move on to the next cycle: //.. // => _W__X__Y__Z_ //.. } } // *** 'shiftAndInsert' overloads: *** template <class ALLOCATOR> inline void ArrayPrimitives_Imp::shiftAndInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer begin, typename bsl::allocator_traits<ALLOCATOR>::pointer end, bslmf::MovableRef< typename bsl::allocator_traits<ALLOCATOR>::value_type> value, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_COPYABLE_TRAITS> *) { BSLS_ASSERT_SAFE(begin != end); // the range is non-empty typedef typename bsl::allocator_traits<ALLOCATOR>::value_type ValueType; // ALIASING: If 'value' is a reference into the array '[begin, end)', // then moving the array first might introduce a change in 'value'. // Fortunately we can easily predict its new position after the shift. ValueType *valuePtr = BSLS_UTIL_ADDRESSOF(bslmf::MovableRefUtil::access(value)); if (begin <= valuePtr && valuePtr < end) { valuePtr += 1; // new address after the shift } #if defined(BSLS_PLATFORM_PRAGMA_GCC_DIAGNOSTIC_GCC) // clang does not support this pragma #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wclass-memaccess" #endif // shift std::memmove(begin + 1, begin, (end - begin) * sizeof(ValueType)); // insert bsl::allocator_traits<ALLOCATOR>::construct( allocator, begin, bslmf::MovableRefUtil::move_if_noexcept(*valuePtr)); #if defined(BSLS_PLATFORM_PRAGMA_GCC_DIAGNOSTIC_GCC) #pragma GCC diagnostic pop #endif } template <class ALLOCATOR> inline void ArrayPrimitives_Imp::shiftAndInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer begin, typename bsl::allocator_traits<ALLOCATOR>::pointer end, bslmf::MovableRef< typename bsl::allocator_traits<ALLOCATOR>::value_type> value, ALLOCATOR allocator, bslmf::MetaInt<e_BITWISE_MOVEABLE_TRAITS> *) { BSLS_ASSERT_SAFE(begin != end); // the range is non-empty typedef typename bsl::allocator_traits<ALLOCATOR>::value_type ValueType; // ALIASING: If 'value' is a reference into the array '[begin, end)', // then moving the array first might introduce a change in 'value'. // Fortunately we can easily predict its new position after the shift. ValueType *valuePtr = BSLS_UTIL_ADDRESSOF(bslmf::MovableRefUtil::access(value)); if (begin <= valuePtr && valuePtr < end) { valuePtr += 1; // new address after the shift } // shift size_t bytesNum = (end - begin) * sizeof(ValueType); #if defined(BSLS_PLATFORM_PRAGMA_GCC_DIAGNOSTIC_GCC) // clang does not support this pragma #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wclass-memaccess" #endif std::memmove(begin + 1, begin, bytesNum); class ElementsProctor { // Moves the elements back if 'construct' throws. // DATA ValueType *d_begin; size_t d_bytesNum; public: // CREATORS ElementsProctor(ValueType *p, size_t n) : d_begin(p), d_bytesNum(n) {} ~ElementsProctor() { if(d_bytesNum) std::memmove(d_begin, d_begin + 1, d_bytesNum); } // MANIPULATORS void release() { d_bytesNum = 0; } } proctor(begin, bytesNum); // insert bsl::allocator_traits<ALLOCATOR>::construct( allocator, begin, bslmf::MovableRefUtil::move_if_noexcept(*valuePtr)); proctor.release(); #if defined(BSLS_PLATFORM_PRAGMA_GCC_DIAGNOSTIC_GCC) #pragma GCC diagnostic pop #endif } template <class ALLOCATOR> inline void ArrayPrimitives_Imp::shiftAndInsert( typename bsl::allocator_traits<ALLOCATOR>::pointer begin, typename bsl::allocator_traits<ALLOCATOR>::pointer end, bslmf::MovableRef< typename bsl::allocator_traits<ALLOCATOR>::value_type> value, ALLOCATOR allocator, bslmf::MetaInt<e_NIL_TRAITS> *) { BSLS_ASSERT_SAFE(begin != end); // the range is non-empty typedef typename bsl::allocator_traits<ALLOCATOR>::value_type ValueType; // ALIASING: If 'value' is a reference into the array '[begin, end)', // then moving the array first might introduce a change in 'value'. // Fortunately we can easily predict its new position after the shift. ValueType *valuePtr = BSLS_UTIL_ADDRESSOF(bslmf::MovableRefUtil::access(value)); if (begin <= valuePtr && valuePtr < end) { valuePtr += 1; // new address after the shift } // Key to the transformation diagrams: //.. // A...G original contents of '[toBegin, toEnd)' ("tail") // a...g moved-from or copied values // v moved 'value' ("input") // _____ uninitialized array elements // [...] part of array protected by an exception guard object //.. //.. // Transformation: ABCDEFG_[] => ABCDEFg[G]. //.. bsl::allocator_traits<ALLOCATOR>::construct( allocator, end, bslmf::MovableRefUtil::move_if_noexcept(*(end - 1))); bslalg::AutoArrayDestructor<ValueType, ALLOCATOR> guard( end, end + 1, allocator); //.. // Transformation: ABCDEFg[G] => aABCDEF[G]. //.. ValueType *dst = end; ValueType *src = end - 1; while (src != begin) { *--dst = bslmf::MovableRefUtil::move_if_noexcept(*--src); } //.. // Transformation: aABCDEFG[G] => vABCDEF[G]. //.. *begin = bslmf::MovableRefUtil::move_if_noexcept(*valuePtr); guard.release(); } } // close package namespace #ifndef BDE_OPENSOURCE_PUBLICATION // BACKWARD_COMPATIBILITY // ============================================================================ // BACKWARD COMPATIBILITY // ============================================================================ typedef bslalg::ArrayPrimitives bslalg_ArrayPrimitives; // This alias is defined for backward compatibility. #endif // BDE_OPENSOURCE_PUBLICATION -- BACKWARD_COMPATIBILITY } // close enterprise namespace #if defined(BSLALG_ARRAYPRIMITIVES_CANNOT_REMOVE_POINTER_FROM_FUNCTION_POINTER) # undef BSLALG_ARRAYPRIMITIVES_CANNOT_REMOVE_POINTER_FROM_FUNCTION_POINTER #endif #else // if ! defined(DEFINED_BSLALG_ARRAYPRIMITIVES_H) # error Not valid except when included from bslalg_arrayprimitives.h #endif // ! defined(COMPILING_BSLALG_ARRAYPRIMITIVES_H) #endif // ! defined(INCLUDED_BSLALG_ARRAYPRIMITIVES_CPP03) // ---------------------------------------------------------------------------- // Copyright 2023 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 ----------------------------------