Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bsltf_stdstatefulallocator
[Package bsltf]

Provide a minimal standard compliant allocator. More...

Namespaces

namespace  bsltf

Detailed Description

Outline
Purpose:
Provide a minimal standard compliant allocator.
Classes:
bsltf::StdStatefulAllocator standard compliant allocator managing state
See also:
Component bsltf_stdtestallocator
Description:
This component provides an allocator, bsltf::StdStatefulAllocator, that defines the minimal interface to comply with section 17.6.3.5 ([allocator.requirements]) of the C++11 standard, while still providing an externally visible and potentially distinct state for each allocator object. This type can be used to verify that constructs designed to support a standard-compliant allocator access the allocator only through the standard-defined interface.
StdStatefulAllocator delegates its operations to the allocator passed at construction (or the default allocator if no allocator is passed) that is also the sole attribute of this class. In most tests, a bslma::TestAllocator will be passed.
The key differences between this test allocator and a regular BDE allocator are:
  • This allocator does not support the scoped allocation model, so that elements in a container will often have a different allocator to the container object itself.
  • This allocator may propagate through copy operations, move operations and swap operations, depending on how the template is configured as it is instantiated.
Usage:
This section illustrates intended use of this component.
Example 1: Testing The Support for STL-Compliant Allocator:
In this example we will verify that a type supports the use of a STL-compliant allocator.
First, we define a simple container type intended to be used with a C++11 standard compliant allocator:
  template <class TYPE, class ALLOCATOR>
  class MyContainer {
      // This container type is parameterized on a standard allocator type
      // and contains a single object, always initialized, which can be
      // replaced and accessed.

      // DATA MEMBERS
      ALLOCATOR  d_allocator;  // allocator used to supply memory (held, not
                               // owned)

      TYPE      *d_object_p;   // pointer to the contained object

    public:
      // CREATORS
      MyContainer(const TYPE& object, const ALLOCATOR& allocator);
          // Create an container containing the specified 'object', using the
          // specified 'allocator' to supply memory.

      ~MyContainer();
          // Destroy this container.

      // MANIPULATORS
      TYPE& object();
          // Return a reference providing modifiable access to the object
          // contained in this container.

      // ACCESSORS
      const TYPE& object() const;
          // Return a reference providing non-modifiable access to the object
          // contained in this container.
  };
Then, we define the member functions of MyContainer:
  // CREATORS
  template <class TYPE, class ALLOCATOR>
  MyContainer<TYPE, ALLOCATOR>::MyContainer(const TYPE&      object,
                                            const ALLOCATOR& allocator)
  : d_allocator(allocator)
  {
      d_object_p = d_allocator.allocate(1);
      new (static_cast<void *>(d_object_p)) TYPE(object);
  }

  template <class TYPE, class ALLOCATOR>
  MyContainer<TYPE, ALLOCATOR>::~MyContainer()
  {
      d_object_p->~TYPE();
      d_allocator.deallocate(d_object_p, 1);
  }

  // MANIPULATORS
  template <class TYPE, class ALLOCATOR>
  TYPE& MyContainer<TYPE, ALLOCATOR>::object()
  {
      return *d_object_p;
  }

  // ACCESSORS
  template <class TYPE, class ALLOCATOR>
  const TYPE& MyContainer<TYPE, ALLOCATOR>::object() const
  {
      return *d_object_p;
  }
Now, we use bsltf::StdStatefulAllocator to implement a simple test for MyContainer to verify it correctly uses a parameterized allocator using only the C++11 standard methods:
  bslma::TestAllocator oa("object", veryVeryVeryVerbose);
  {
      typedef MyContainer<int, bsltf::StdStatefulAllocator<int> > Obj;

      Obj        mX(2, bsltf::StdStatefulAllocator<int>(&oa));
      const Obj& X = mX;
      assert(sizeof(int) == oa.numBytesInUse());

      assert(X.object() == 2);

      mX.object() = -10;
      assert(X.object() == -10);
  }

  assert(0 == oa.numBytesInUse());