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

Detailed Description

Outline

Purpose

Provide a utility to build a Datum object holding an array.

Classes

See also
bdld_datum

Description

This component defines a mechanism, bdld::DatumArrayBuilder, used to populate a Datum array value in an exception-safe manner. In addition to providing exception safety, a DatumArrayBuilder is particularly useful when the length of the array to be constructed is not known in advance. The user can append elements to the datum array as needed, and when there are no more elements to append the user calls commit and ownership of the populated Datum object is transferred to the caller. After the call to commit, no additional elements can be appended to the Datum array value.

Usage

This section illustrates intended use of this component.

Example 1: Using a DatumArrayBuilder to Create a Datum array.

Suppose we receive a string that is constructed by streaming a bunch of values together in the format shown below:

"2.34,4,hi there,true"

Notice that the values are separated by a ,. Also note that a , is not allowed to be part of a string value to simplify the implementation of the utility that parses this string. The following code snippets illustrate how to create a Datum object that holds an array of Datum objects constructed using the streamed values.

First we define a function nextValue that we will use to tokenize the input string:

/// Extract the next value from a list of comma separated values in the
/// specified `input` string and load it in the specified `value`.
/// Return the index of the next value within `input`.
bsl::size_t nextValue(bsl::string *value, const bsl::string& input)
{
if (input.empty()) {
}
int start = 0;
bsl::size_t nextIndex = input.find(',', start);
if (bsl::string::npos != nextIndex) {
*value = input.substr(start, nextIndex - start);
}
else {
*value = input.substr(start);
}
return nextIndex;
}
Definition bslstl_string.h:1281
basic_string substr(size_type position=0, size_type numChars=npos) const
Definition bslstl_string.h:7263
size_type find(const basic_string &substring, size_type position=0) const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:6732
static const size_type npos
Definition bslstl_string.h:1676
bool empty() const BSLS_KEYWORD_NOEXCEPT
Return true if this string has length 0, and false otherwise.
Definition bslstl_string.h:6631

Next, we define a function convertToDatum that will convert a string token into a Datum scalar value:

// Convert the specified `token` into the appropriate type of scalar
// value and then create and return a `Datum` object using that value.
// Use the specified `basicAllocator` to supply memory.
bdld::Datum convertToDatum(const bsl::string& token,
bslma::Allocator *basicAllocator)
{
bool isInteger = true;
bool isDouble = false;
bool isBoolean = false;
for (bsl::size_t i = 0; i < token.size(); ++i) {
if (!isdigit(token[i])) {
if ('.' == token[i] && !isDouble) {
isDouble = true;
isInteger = false;
continue;
}
isInteger = false;
isDouble = false;
break;
}
}
if (!isInteger && !isDouble) {
if ("true" == token || "false" == token) {
isBoolean = true;
}
}
if (isInteger) { // integer token
return bdld::Datum::createInteger(atoi(token.c_str()));
}
else if (isDouble) { // double token
return bdld::Datum::createDouble(atof(token.c_str()));
}
else if (isBoolean) { // boolean token
return bdld::Datum::createBoolean("true" == token ? true : false);
}
else { // string value
return bdld::Datum::copyString(token, basicAllocator);
}
}
Definition bdld_datum.h:787
static Datum copyString(const char *string, SizeType length, const AllocatorType &allocator)
static Datum createDouble(double value)
Definition bdld_datum.h:3820
static Datum createInteger(int value)
Return, by value, a datum having the specified int value.
Definition bdld_datum.h:3848
static Datum createBoolean(bool value)
Return, by value, a datum having the specified bool value.
Definition bdld_datum.h:3723
const CHAR_TYPE * c_str() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:6705
size_type size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:6592
Definition bslma_allocator.h:457

Now, in our example main, we tokenize an input string "2.34,4,hi there,true" to populate a Datum array containing the values '[2.34, 4, "hi there", true]':

void exampleMain() {
const bsl::string input("2.34,4,hi there,true", &allocator);
Definition bslma_testallocator.h:384

Here, we create a DatumArrayBuilder, and iterate over the parsed tokens from input, using pushBack on the array builder to add the tokens to a Datum array value:

bdld::DatumArrayBuilder builder(0, &allocator);
bsl::string str(input, &allocator);
bsl::string value;
bsl::size_t nextIndex;
do {
nextIndex = nextValue(&value, str);
builder.pushBack(convertToDatum(value, &allocator));
if (bsl::string::npos == nextIndex) {
break;
}
str = str.substr(nextIndex + 1);
} while (bsl::string::npos != nextIndex);
bdld::Datum result = builder.commit();
Definition bdld_datumarraybuilder.h:223

Notice that calling commit on the DatumArrayBuilder adopts ownership for the returned Datum object, and that the behavior is undefined if pushBack is called after commit.

Finally, we verify that result has the expected array value, and destroy the created Datum value:

assert(true == result.isArray());
assert(4 == result.theArray().length());
assert(true == result.theArray()[0].isDouble());
assert(2.34 == result.theArray()[0].theDouble());
assert(true == result.theArray()[1].isInteger());
assert(4 == result.theArray()[1].theInteger());
assert(true == result.theArray()[2].isString());
assert("hi there" == result.theArray()[2].theString());
assert(true == result.theArray()[3].isBoolean());
assert(true == result.theArray()[3].theBoolean());
// Destroy the 'Datum' object.
bdld::Datum::destroy(result, &allocator);
}
size_type length() const
Return a const pointer to the length of the array.
Definition bdld_datum.h:4886
DatumArrayRef theArray() const
Definition bdld_datum.h:4257
bool isArray() const
Definition bdld_datum.h:4119
static void destroy(const Datum &value, const AllocatorType &allocator)