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:
-
- See also:
- Component bdld_datum, Component bdld_datummapbuilder
-
- Description:
- This component defines a mechanism,
bdld::DatumMapOwningKeysBuilder
, used to populate a Datum
map value in an exception-safe manner. In addition to providing exception safety, a DatumMapOwningKeysBuilder
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_datummapbuilder
is that this component makes a copy of the map entries keys and the resulting Datum
object owns 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. The values in that map can be different types and keys must be protected from destruction as this map object can be passed out of scope. The following code illustrates how to use
bdld::DatumMapOwningKeysBuilder
to create such map easily.
- First, we need data to fill our map:
bslma::TestAllocator ta("test", veryVeryVerbose);
bsl::string firstName = "firstName";
bsl::string lastName = "lastName";
bsl::string gender = "gender";
bsl::string age = "age";
DatumMapEntry bartData[] = {
DatumMapEntry(firstName, Datum::createStringRef("Bart", &ta)),
DatumMapEntry(lastName, Datum::createStringRef("Simpson", &ta)),
DatumMapEntry(gender, Datum::createStringRef("male", &ta)),
DatumMapEntry(age, Datum::createInteger(10))
};
const size_t DATA_SIZE = sizeof(bartData) / sizeof(DatumMapEntry);
const size_t KEYS_SIZE = firstName.length()
+ lastName.length()
+ gender.length()
+ age.length();
Next, we create an object of DatumMapOwningKeysBuilder
class with initial capacity sufficient for storing all our data: DatumMapOwningKeysBuilder builder(DATA_SIZE, KEYS_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());