// bsltf_allocemplacabletesttype.h -*-C++-*- #ifndef INCLUDED_BSLTF_ALLOCEMPLACABLETESTTYPE #define INCLUDED_BSLTF_ALLOCEMPLACABLETESTTYPE #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide an allocating test class used to test 'emplace' methods. // //@CLASSES: // bsltf::AllocEmplacableTestType: allocating test class with 0..14 arguments // //@SEE_ALSO: bsltf_allocargumenttype, bsltf_templatetestfacility // //@DESCRIPTION: This component provides a (value-semantic) attribute class, // 'bsltf::AllocEmplacableTestType', that is used to ensure that arguments are // forwarded correctly to a type's constructor. This component is similar to // 'bsltf_emplacabletesttype', but provides a type that allocates on // construction. // ///Attributes ///---------- //.. // Name Type Default // ------- ----------------------------- ------- // arg01 bsltf::AllocArgumentType< 1> -1 // arg02 bsltf::AllocArgumentType< 2> -1 // arg03 bsltf::AllocArgumentType< 3> -1 // arg04 bsltf::AllocArgumentType< 4> -1 // arg05 bsltf::AllocArgumentType< 5> -1 // arg06 bsltf::AllocArgumentType< 6> -1 // arg07 bsltf::AllocArgumentType< 7> -1 // arg08 bsltf::AllocArgumentType< 8> -1 // arg09 bsltf::AllocArgumentType< 9> -1 // arg10 bsltf::AllocArgumentType<10> -1 // arg11 bsltf::AllocArgumentType<11> -1 // arg12 bsltf::AllocArgumentType<12> -1 // arg13 bsltf::AllocArgumentType<13> -1 // arg14 bsltf::AllocArgumentType<14> -1 //.. // ///Usage ///----- // In this section we show intended use of this component. // ///Example 1: Testing Methods With Argument Forwarding /// - - - - - - - - - - - - - - - - - - - - - - - - - - - - // In this example, we will utilize 'bsltf::AllocEmplacableTestType' to // test the implementation of a container's 'emplace' method. // // First, we create an elided definition of a container class, 'MyContainer', // and show the signature of the 'emplace' method we intend to test: //.. // // container.h // // ----------- // template <class TYPE> // class Container { // // This class template implements a value-semantic container type // // holding elements of the (template parameter) type 'TYPE'. This // // class provides an 'emplace' method that constructs the element by // // forwarding a variable number of arguments to the 'TYPE' constructor. // // // ... // // // MANIPULATORS // template <class... Args> // void emplace(Args&&... arguments); // // Insert into this container a newly created 'TYPE' object, // // constructed by forwarding the specified (variable number of) // // 'arguments' to the corresponding constructor of 'TYPE'. // // // ... // }; //.. // Then, we provide test machinery that will invoke the 'emplace' method with // variable number of arguments: //.. // // container.t.cpp // // --------------- // // template <class T> // bslmf::MovableRef<T> forwardCtorArg(T& argument, bsl::true_type); // // Return 'bslmf::MovableRef' to the specified 'argument'. // // template <class T> // const T& forwardCtorArg(T& argument, bsl::false_type) // // Return a reference providing non-modifiable access to the // // specified 'argument'. // // template <int N_ARGS, bool MOVE_ARG_01, bool MOVE_ARG_02> // void testCaseHelper() // // Call 'emplace' on the container and verify that value was correctly // // constructed and inserted into the container. Forward (template // // parameter) 'N_ARGS' arguments to the 'emplace' method and ensure 1) // // that values are properly passed to the constructor of // // 'bsltf::AllocEmplacableTestType', 2) that the allocator is correctly // // configured for each argument in the newly inserted element in // // 'target', and 3) that the arguments are forwarded using copy // // ('false') or move semantics ('true') based on bool template // // parameters 'MOVE_ARG_01' ... 'MOVE_ARG_02'. // { // bslma::TestAllocator ta; //.. // Here, we use 'AllocEmplacableTestType' as the contained type to ensure the // arguments to the 'emplace' method are correctly forwarded to the contained // type's constructor: //.. // Container<bsltf::AllocEmplacableTestType> mX(&ta); // const Container<bsltf::AllocEmplacableTestType>& X = mX; // // // Prepare the arguments // bslma::TestAllocator aa("args", veryVeryVeryVerbose); // // bsltf::AllocArgumentType<1> A01(18, &aa); // bsltf::AllocArgumentType<2> A02(33, &aa); //.. // Then, we call 'emplace' supplying test arguments, which should call the // correct constructor of 'AllocEmplacableTestType' (which we will later // verify): //.. // const bsl::integral_constant<bool, MOVE_ARG_01> MOVE_01 = {}; // const bsl::integral_constant<bool, MOVE_ARG_02> MOVE_02 = {}; // switch (N_ARGS) { // case 0: { // mX.emplace(); // } break; // case 1: { // mX.emplace(forwardCtorArg(A01, MOVE_01)); // } break; // case 2: { // mX.emplace(forwardCtorArg(A01, MOVE_01), // forwardCtorArg(A02, MOVE_02)); // } break; // default: { // assert(0); // } break; // } //.. // We verify the correct arguments were forwarded to the // 'AllocEmplcableTestType': //.. // // Verify that, depending on the corresponding template parameters, // // arguments were copied or moved. // assert(MOVE_ARG_01 == (bsltf::MoveState::e_MOVED == A01.movedFrom())); // assert(MOVE_ARG_02 == (bsltf::MoveState::e_MOVED == A02.movedFrom())); // // // Verify that the element was constructed correctly. // const bsltf::AllocEmplacableTestType& V = X.front(); // // assert(18 == V.arg01() || N_ARGS < 1); // assert(33 == V.arg02() || N_ARGS < 2); // } //.. // Finally, we call our templatized test case helper with a variety of template // arguments: //.. // void testCase() // { // // Testing 'emplace' with 0 arguments. // testCaseHelper<0, false, false>(); // // // Testing 'emplace' with 1 argument. // testCaseHelper<1, false, false>(); // testCaseHelper<1, true, false>(); // // // Testing 'emplace' with 2 arguments. // testCaseHelper<2, false, false>(); // testCaseHelper<2, true, false>(); // testCaseHelper<2, false, true >(); // testCaseHelper<2, true, true >(); // } //.. #include <bslscm_version.h> #include <bslma_usesbslmaallocator.h> #include <bsltf_allocargumenttype.h> namespace BloombergLP { namespace bslma { class Allocator; } namespace bsltf { // ============================= // class AllocEmplacableTestType // ============================= class AllocEmplacableTestType { // This class provides a test object used to check that the arguments // passed for creating an object with an in-place representation are of the // correct types and values. public: // TYPEDEFS typedef bsltf::AllocArgumentType< 1> ArgType01; typedef bsltf::AllocArgumentType< 2> ArgType02; typedef bsltf::AllocArgumentType< 3> ArgType03; typedef bsltf::AllocArgumentType< 4> ArgType04; typedef bsltf::AllocArgumentType< 5> ArgType05; typedef bsltf::AllocArgumentType< 6> ArgType06; typedef bsltf::AllocArgumentType< 7> ArgType07; typedef bsltf::AllocArgumentType< 8> ArgType08; typedef bsltf::AllocArgumentType< 9> ArgType09; typedef bsltf::AllocArgumentType<10> ArgType10; typedef bsltf::AllocArgumentType<11> ArgType11; typedef bsltf::AllocArgumentType<12> ArgType12; typedef bsltf::AllocArgumentType<13> ArgType13; typedef bsltf::AllocArgumentType<14> ArgType14; private: // DATA ArgType01 d_arg01; ArgType02 d_arg02; ArgType03 d_arg03; ArgType04 d_arg04; ArgType05 d_arg05; ArgType06 d_arg06; ArgType07 d_arg07; ArgType08 d_arg08; ArgType09 d_arg09; ArgType10 d_arg10; ArgType11 d_arg11; ArgType12 d_arg12; ArgType13 d_arg13; ArgType14 d_arg14; // CLASS DATA static int s_numDeletes; // Track number of times the destructor is called. public: // CLASS METHODS static int getNumDeletes(); // Return the number of times an object of this type has been // destroyed. // CREATORS AllocEmplacableTestType(bslma::Allocator *basicAllocator = 0); explicit AllocEmplacableTestType(ArgType01 arg01, bslma::Allocator *basicAllocator = 0); AllocEmplacableTestType(ArgType01 arg01, ArgType02 arg02, bslma::Allocator *basicAllocator = 0); AllocEmplacableTestType(ArgType01 arg01, ArgType02 arg02, ArgType03 arg03, bslma::Allocator *basicAllocator = 0); AllocEmplacableTestType(ArgType01 arg01, ArgType02 arg02, ArgType03 arg03, ArgType04 arg04, bslma::Allocator *basicAllocator = 0); AllocEmplacableTestType(ArgType01 arg01, ArgType02 arg02, ArgType03 arg03, ArgType04 arg04, ArgType05 arg05, bslma::Allocator *basicAllocator = 0); AllocEmplacableTestType(ArgType01 arg01, ArgType02 arg02, ArgType03 arg03, ArgType04 arg04, ArgType05 arg05, ArgType06 arg06, bslma::Allocator *basicAllocator = 0); AllocEmplacableTestType(ArgType01 arg01, ArgType02 arg02, ArgType03 arg03, ArgType04 arg04, ArgType05 arg05, ArgType06 arg06, ArgType07 arg07, bslma::Allocator *basicAllocator = 0); AllocEmplacableTestType(ArgType01 arg01, ArgType02 arg02, ArgType03 arg03, ArgType04 arg04, ArgType05 arg05, ArgType06 arg06, ArgType07 arg07, ArgType08 arg08, bslma::Allocator *basicAllocator = 0); AllocEmplacableTestType(ArgType01 arg01, ArgType02 arg02, ArgType03 arg03, ArgType04 arg04, ArgType05 arg05, ArgType06 arg06, ArgType07 arg07, ArgType08 arg08, ArgType09 arg09, bslma::Allocator *basicAllocator = 0); AllocEmplacableTestType(ArgType01 arg01, ArgType02 arg02, ArgType03 arg03, ArgType04 arg04, ArgType05 arg05, ArgType06 arg06, ArgType07 arg07, ArgType08 arg08, ArgType09 arg09, ArgType10 arg10, bslma::Allocator *basicAllocator = 0); AllocEmplacableTestType(ArgType01 arg01, ArgType02 arg02, ArgType03 arg03, ArgType04 arg04, ArgType05 arg05, ArgType06 arg06, ArgType07 arg07, ArgType08 arg08, ArgType09 arg09, ArgType10 arg10, ArgType11 arg11, bslma::Allocator *basicAllocator = 0); AllocEmplacableTestType(ArgType01 arg01, ArgType02 arg02, ArgType03 arg03, ArgType04 arg04, ArgType05 arg05, ArgType06 arg06, ArgType07 arg07, ArgType08 arg08, ArgType09 arg09, ArgType10 arg10, ArgType11 arg11, ArgType12 arg12, bslma::Allocator *basicAllocator = 0); AllocEmplacableTestType(ArgType01 arg01, ArgType02 arg02, ArgType03 arg03, ArgType04 arg04, ArgType05 arg05, ArgType06 arg06, ArgType07 arg07, ArgType08 arg08, ArgType09 arg09, ArgType10 arg10, ArgType11 arg11, ArgType12 arg12, ArgType13 arg13, bslma::Allocator *basicAllocator = 0); AllocEmplacableTestType(ArgType01 arg01, ArgType02 arg02, ArgType03 arg03, ArgType04 arg04, ArgType05 arg05, ArgType06 arg06, ArgType07 arg07, ArgType08 arg08, ArgType09 arg09, ArgType10 arg10, ArgType11 arg11, ArgType12 arg12, ArgType13 arg13, ArgType14 arg14, bslma::Allocator *basicAllocator = 0); // Create an 'AllocEmplacableTestType' by initializing corresponding // attributes with the specified 'arg01'..'arg14', and initializing any // remaining attributes with their default value (-1). Optionally // specify a 'basicAllocator' used to supply memory. If // 'basicAllocator' is 0, the currently installed default allocator is // used. AllocEmplacableTestType( const AllocEmplacableTestType& original, bslma::Allocator *basicAllocator = 0); // Create an allocating, in-place test object having the same value as // the specified 'original'. Optionally specify a 'basicAllocator' // used to supply memory. If 'basicAllocator' is 0, the currently // installed default allocator is used. ~AllocEmplacableTestType(); // Increment the count of calls to this destructor, and destroy this // object. // MANIPULATORS #if BSLS_COMPILERFEATURES_CPLUSPLUS >= 201103L AllocEmplacableTestType& operator=( const AllocEmplacableTestType& rhs) = default; // Assign to this object the value of the specified 'rhs' object, and // return a reference providing modifiable access to this object. #else //! AllocEmplacableTestType& operator=( // const AllocEmplacableTestType& rhs) = default; #endif // ACCESSORS bslma::Allocator *allocator() const; // Return the allocator used to supply memory for this object. const ArgType01& arg01() const; const ArgType02& arg02() const; const ArgType03& arg03() const; const ArgType04& arg04() const; const ArgType05& arg05() const; const ArgType06& arg06() const; const ArgType07& arg07() const; const ArgType08& arg08() const; const ArgType09& arg09() const; const ArgType10& arg10() const; const ArgType11& arg11() const; const ArgType12& arg12() const; const ArgType13& arg13() const; const ArgType14& arg14() const; // Return the value of the correspondingly numbered argument that was // passed to the constructor of this object. bool isEqual(const AllocEmplacableTestType& rhs) const; // Return 'true' if the specified 'rhs' has the same value as this // object, and 'false' otherwise. Two 'AllocEmplacableTestType' // objects have the same value if each of their corresponding // attributes have the same value. }; // FREE OPERATORS bool operator==(const AllocEmplacableTestType& lhs, const AllocEmplacableTestType& rhs); // Return 'true' if the specified 'lhs' and 'rhs' objects have the same // value, and 'false' otherwise. Two 'AllocEmplacableTestType' objects // have the same value if each of their corresponding attributes have the // same value. bool operator!=(const AllocEmplacableTestType& lhs, const AllocEmplacableTestType& rhs); // Return 'true' if the specified 'lhs' and 'rhs' objects do not have the // same value, and 'false' otherwise. Two 'AllocEmplacableTestType' // objects do not have the same value if any of their corresponding // attributes do not have the same value. // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // ----------------------------- // class AllocEmplacableTestType // ----------------------------- // ACCESSORS inline const AllocEmplacableTestType::ArgType01& AllocEmplacableTestType::arg01() const { return d_arg01; } inline const AllocEmplacableTestType::ArgType02& AllocEmplacableTestType::arg02() const { return d_arg02; } inline const AllocEmplacableTestType::ArgType03& AllocEmplacableTestType::arg03() const { return d_arg03; } inline const AllocEmplacableTestType::ArgType04& AllocEmplacableTestType::arg04() const { return d_arg04; } inline const AllocEmplacableTestType::ArgType05& AllocEmplacableTestType::arg05() const { return d_arg05; } inline const AllocEmplacableTestType::ArgType06& AllocEmplacableTestType::arg06() const { return d_arg06; } inline const AllocEmplacableTestType::ArgType07& AllocEmplacableTestType::arg07() const { return d_arg07; } inline const AllocEmplacableTestType::ArgType08& AllocEmplacableTestType::arg08() const { return d_arg08; } inline const AllocEmplacableTestType::ArgType09& AllocEmplacableTestType::arg09() const { return d_arg09; } inline const AllocEmplacableTestType::ArgType10& AllocEmplacableTestType::arg10() const { return d_arg10; } inline const AllocEmplacableTestType::ArgType11& AllocEmplacableTestType::arg11() const { return d_arg11; } inline const AllocEmplacableTestType::ArgType12& AllocEmplacableTestType::arg12() const { return d_arg12; } inline const AllocEmplacableTestType::ArgType13& AllocEmplacableTestType::arg13() const { return d_arg13; } inline const AllocEmplacableTestType::ArgType14& AllocEmplacableTestType::arg14() const { return d_arg14; } inline bslma::Allocator *AllocEmplacableTestType::allocator() const { return d_arg01.allocator(); } inline bool AllocEmplacableTestType::isEqual(const AllocEmplacableTestType& rhs) const { return d_arg01 == rhs.d_arg01 && d_arg02 == rhs.d_arg02 && d_arg03 == rhs.d_arg03 && d_arg04 == rhs.d_arg04 && d_arg05 == rhs.d_arg05 && d_arg06 == rhs.d_arg06 && d_arg07 == rhs.d_arg07 && d_arg08 == rhs.d_arg08 && d_arg09 == rhs.d_arg09 && d_arg10 == rhs.d_arg10 && d_arg11 == rhs.d_arg11 && d_arg12 == rhs.d_arg12 && d_arg13 == rhs.d_arg13 && d_arg14 == rhs.d_arg14; } // FREE OPERATORS inline bool operator==(const bsltf::AllocEmplacableTestType& lhs, const bsltf::AllocEmplacableTestType& rhs) { return lhs.isEqual(rhs); } inline bool operator!=(const bsltf::AllocEmplacableTestType& lhs, const bsltf::AllocEmplacableTestType& rhs) { return !lhs.isEqual(rhs); } } // close package namespace // TRAITS namespace bslma { template <> struct UsesBslmaAllocator<bsltf::AllocEmplacableTestType> : bsl::true_type { }; } // close namespace bslma } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2016 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 ----------------------------------