BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsltf_allocemplacabletesttype

Detailed Description

Outline

Purpose

Provide an allocating test class used to test emplace methods.

Classes

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

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'.
{
Definition bslma_testallocator.h:384
Definition bslmf_movableref.h:751

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);

Then, we call emplace supplying test arguments, which should call the correct constructor of AllocEmplacableTestType (which we will later verify):

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);
}
Definition bsltf_allocemplacabletesttype.h:236
@ e_MOVED
Definition bsltf_movestate.h:122

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 >();
}