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

Detailed Description

Outline

Purpose

Provide a variant type for command-line-option values.

Classes

See also
balcl_optiontype, balcl_commandline

Description

This component provides a value-semantic class, balcl::OptionValue, that can have a value of any of the types specified by balcl::OptionType – i.e., any of the values that can be associated with a command-line option by balcl::CommandLine. The balcl::OptionValue class has two related states:

  1. A default-constructed balcl::OptionValue object is in the "unset state" – meaning that no type has been defined for a value (its type is void). In this state, balcl::OptionType::e_VOID == type() and false == hasNonVoidType(). To have a value, a type must be specified for the value by using the setType method or using one of the constructors that define an initial value. {Example 1} shows how this state can be set and reset.
  2. If a balcl::OptionValue object has a (non-void) type it can have a value of that type or be in a "null state". Objects in the null state can be used to represent the value of command-line options that were not entered on the command line (assuming no default value was specified for the option). {Example 2} shows how this feature can be used.

Usage

This section illustrates intended use of this component.

Example 1: Basic Use of balcl::OptionValue

The following snippets of code illustrate how to create and use a balcl::OptionValue object. Note that balcl::OptionValue objects are typically used in a description of a sequence of command-line options (see balcl_optiontype ).

First, we create a default balcl::OptionValue, valueA, and observe that it is in the unset state:

assert(false == valueA.hasNonVoidType());
assert(balcl::OptionType::e_VOID == valueA.type());
Definition balcl_optionvalue.h:393
OptionType::Enum type() const
bool hasNonVoidType() const
Definition balcl_optionvalue.h:900
@ e_VOID
Definition balcl_optiontype.h:250

Next, we create a second balcl::OptionValue having the value 5, and then confirm its value and observe that it does not compare equal to the valueA:

assert(true == valueB.hasNonVoidType());
assert(balcl::OptionType::e_INT == valueB.type());
assert(5 == valueB.the<int>());
assert(valueA != valueB);
@ e_INT
Definition balcl_optiontype.h:253

Then, we call the reset method of valueB resetting it to the unset state, and observe that valueA now compares equal to valueB:

valueB.reset();
assert(valueA == valueB);

Now, we change the type of valueA so that it can be hold a double value:

assert(true == valueA.hasNonVoidType());
assert(balcl::OptionType::e_DOUBLE == valueA.type());
assert(double() == valueA.the<double>());
valueA.set(6.0);
assert(6.0 == valueA.the<double>());
void set(const TYPE &value)
Definition balcl_optionvalue.h:850
void setType(OptionType::Enum type)
Definition balcl_optionvalue.h:873
TYPE & the()
Definition balcl_optionvalue.h:881
@ e_DOUBLE
Definition balcl_optiontype.h:255

Finally, we set the object to the null state. Notice that the type of that value is not changed:

valueA.setNull();
assert(true == valueA.isNull());
assert(balcl::OptionType::e_DOUBLE == valueA.type());
bool isNull() const
Definition balcl_optionvalue.h:906
void setNull()
Definition balcl_optionvalue.h:860

Example 2: Interpreting Option Parser Results

Command-line options have values of many different types (e.g., int, double, string, date) or their values may not be specified – after all, some command-line options may be optional. The balcl::OptionValue class can be used to represent such values.

First, we define MyCommandLineParser, a simple command-line argument parser. This class accepts a description (e.g., option name, value type) of allowable options on construction and provides a parse method that accepts argc and argv, the values made available (by the operating system) to main:

// =========================
// class MyCommandLineParser
// =========================
class MyCommandLineParser {
// ...
public:
// CREATORS
/// Create an object that can parse command-line arguments that
/// satisfy the specified `descriptions`, an array containing the
/// specified `count` elements.
MyCommandLineParser(const MyOptionDescription *descriptions,
bsl::size_t count);
// ...
// MANIPULATORS
/// Parse the command-line options in the specified `argv`, an array
/// having the specified `argc` elements. Return 0 on success --
/// i.e., the options were compatible with the option descriptions
/// specified on construction -- and a non-zero value otherwise.
int parse(int argc, const char **argv);
// ...

After a successful call to the parse method, the results are available by several accessors. Note that the index of a result corresponds to the index of that option in the description provided on construction:

// ACCESSORS
/// Return `true` if the most recent call to `parsed` was successful
/// and `false` otherwise.
bool isParsed() const;
/// Return of the name of the parsed option at the specified `index`
/// position. The behavior is undefined unless
/// `0 <= index < numOptions()` and `true == isParsed()`
const char *name (bsl::size_t index) const;
/// Return a `const` reference to the value (possibly in a null
/// state) of the parsed option at the specified `index` position.
/// The behavior is undefined unless `0 <= index < numOptions()` and
/// `true == isParsed()`.
const balcl::OptionValue& value(bsl::size_t index) const;
/// Return the number of parsed options. The behavior is undefined
/// unless `true == isParsed()`.
bsl::size_t numOptions() const;
// ...
};

Note that neither our option description nor our parser support the concept of default values for options that are not entered on the command line.

Then, we create a description having three allowable options (elided), a parser object, and invoke parse on the arguments available from main:

int main(int argc, const char **argv)
{
MyOptionDescription optionDescriptions[NUM_OPTIONS] = {
// ...
};
MyCommandLineParser parser(optionDescriptions, NUM_OPTIONS);
int rc = parser.parse(argc, argv);
assert(0 == rc);
assert(true == parser.isParsed());

Now, we examine the value of each defined option:

for (bsl::size_t i = 0; i < parser.numOptions(); ++i) {
const char *name = parser.name(i);
const balcl::OptionValue& value = parser.value(i);

Since our (toy) parser has no feature for handling default values for options that are not specified on the command line, we must handle those explicitly.

If the option named "outputDir" was set, we use that value; otherwise, we set a default value, the current directory:

if (0 == bsl::strcmp("outputDir", name)) {
setOutputDir(value.isNull()
? "."
: value.the<bsl::string>().c_str());
}
Definition bdlb_printmethods.h:283

If the option named "verbosityLevel" was set we use that value; otherwise, we set a default value, 1:

if (0 == bsl::strcmp("verbosityLevel", name)) {
setVerbosityLevel(value.isNull()
? 1
: value.the<int>());
}

The option named "caseInsensitive" has no associated value. If that option appeared on the command line, the value of the program flag is set to true, otherwise (false == isNull()) that flag is set to false:

if (0 == bsl::strcmp("caseInsensitive", name)) {
setCaseInsensitivityFlag(value.isNull()
? false
: true);
}
}

Finally, we continue with the execution of our program using the values obtained from the command-line options:

// ...
return 0;
}