Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bsltf_allocemplacabletesttype
[Package bsltf]

Provide an allocating test class used to test emplace methods. More...

Namespaces

namespace  bslma
namespace  bsltf

Detailed Description

Outline
Purpose:
Provide an allocating test class used to test emplace methods.
Classes:
bsltf::AllocEmplacableTestType allocating test class with 0..14 arguments
See also:
Component bsltf_allocargumenttype, Component 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'.
  {
      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 >();
  }