Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bdld_datummapbuilder
[Package bdld]

Provide a utility to build a Datum object holding a map. More...

Namespaces

namespace  bdld

Detailed Description

Outline
Purpose:
Provide a utility to build a Datum object holding a map.
Classes:
bdld::DatumMapBuilder utility to build a Datum object holding a map
See also:
Component bdld_datum, Component bdld_datummapowningkeysbuilder
Description:
This component defines a mechanism, bdld::DatumMapBuilder, used to populate a Datum map value in an exception-safe manner. In addition to providing exception safety, a DatumMapBuilder is particularly useful when the size of the map to be constructed is not known in advance. The user can append elements to the datum map as needed, and when there are no more elements to append the user calls commit or sortAndCommit and ownership of the populated Datum object is transferred to the caller. After calling commit or sortAndCommit, no additional elements can be appended to the Datum map value. Note that sortAndCommit method will sort the populated map (by keys) and tag the resulting Datum map value as sorted. Also note that the user can insert elements in a (ascending) sorted order and tag the map as sorted. The behaviour is undefined if unsorted map is tagged sorted.
The only difference between this component and bdld_datummapowningkeysbuilder is that this component does not make a copy of the map entries keys and the resulting Datum object does not own memory for the map entries keys.
Usage:
This section illustrates intended use of this component.
Example 1: Basic Syntax:
Suppose we need a map for some personal data. And the values in that map can be different types. The following code illustrates how to use bdld::DatumMapBuilder to create such map easily.
First, we need data to fill our map:
  bslma::TestAllocator ta("test", veryVeryVerbose);

  DatumMapEntry bartData[] = {
      DatumMapEntry(StringRef("firstName"),
                    Datum:: createStringRef("Bart", &ta)),
      DatumMapEntry(StringRef("lastName"),
                    Datum:: createStringRef("Simpson", &ta)),
      DatumMapEntry(StringRef("gender"),
                    Datum::createStringRef("male", &ta)),
      DatumMapEntry(StringRef("age"), Datum::createInteger(10))
  };

  const size_t DATA_SIZE  = sizeof(bartData) / sizeof(DatumMapEntry);
Next, we create an object of DatumMapBuilder class with initial capacity sufficient for storing all our data:
  DatumMapBuilder builder(DATA_SIZE, &ta);
Then, we load our builder with these data:
  for (size_t i = 0; i < DATA_SIZE; ++i) {
      builder.pushBack(bartData[i].key(), bartData[i].value());
  }
Next, we adopt the map, held by our builder, by newly created Datum object:
  Datum bart = builder.commit();
Now, we can check that all data have been correctly added to the map at the required order:
  assert(true == bart.isMap());
  assert(DATA_SIZE == bart.theMap().size());

  assert("firstName" == bart.theMap()[0].key());
  assert(true        == bart.theMap()[0].value().isString());
  assert("Bart"      == bart.theMap()[0].value().theString());

  assert("lastName"  == bart.theMap()[1].key());
  assert(true        == bart.theMap()[1].value().isString());
  assert("Simpson"   == bart.theMap()[1].value().theString());

  assert("gender"    == bart.theMap()[2].key());
  assert(true        == bart.theMap()[2].value().isString());
  assert("male"      == bart.theMap()[2].value().theString());

  assert("age"       == bart.theMap()[3].key());
  assert(true        == bart.theMap()[3].value().isInteger());
  assert(10          == bart.theMap()[3].value().theInteger());
Finally, we destroy the Datum object to release all allocated memory correctly:
  Datum::destroy(bart, &ta);
  assert(0 == ta.numBytesInUse());