docopt.cpp
docopt.cpp copied to clipboard
Added ValueOr functions to ease usage of docopt in -fno-exceptions environment
While parsing of the documentation with docopt::docopt() is -fno-exceptions environment friendly, accessing any parsed value is not and requires some boilerplate code like
std::map< std::string, docopt::value > args;
{
args = docopt::docopt(USAGE,
{ argv + 1, argv + argc },
true, // show help if requested
"my_programm 1.0.0"); // version string
}
/* ... */
auto v = args.contains("123") ?
(
args.at("123").isString() ?
args.at("123").asString()
:
"Fallback Value"
)
:
"Fallback Value";
which can at least be simplified like this with the PR
std::map< std::string, docopt::value > args;
{
args = docopt::docopt(USAGE,
{ argv + 1, argv + argc },
true, // show help if requested
"my_programm 1.0.0"); // version string
}
/* ... */
auto v = args.contains("123") ?
args.at("123").asStringOr("Fallback Value")
:
"Fallback Value";
or for those who don't care about unnecessary allocations like this
std::map< std::string, docopt::value > args;
{
args = docopt::docopt(USAGE,
{ argv + 1, argv + argc },
true, // show help if requested
"my_programm 1.0.0"); // version string
}
/* ... */
auto v = args["123"].asStringOr("Fallback Value");
I'd love to add some tests for the functions but I'm not sure where I should add them as the current test run_test.py using the compiled run_testcase.cpp doesn't seem to be optimal to test those functions.
I'd assume the following cases would be helpful:
const std::string test_str = "STR";
const std::string test_other_str = "OTHER STR";
const std::string test_num_str = "123";
const std::vector<std::string> test_str_list = {test_str};
const std::vector<std::string> test_other_str_list = {test_other_str};
// Case 0: Bool Value (true)
const auto v_true = docopt::value(true);
assert(v_true.asBoolOr(true) == true); // <-- This should not use the Or-Value
assert(v_true.asBoolOr(false) == true); // <-- This should not use the Or-Value
assert(v_true.asLongOr(-1) == -1);
assert(v_true.asStringOr(test_str) == test_str);
assert(v_true.asStringListOr(test_str_list) == test_str_list);
// Case 1: Bool Value (false)
const auto v_false = docopt::value(false);
assert(v_false.asBoolOr(true) == false); // <-- This should not use the Or-Value
assert(v_false.asBoolOr(false) == false); // <-- This should not use the Or-Value
assert(v_false.asLongOr(-1) == -1);
assert(v_false.asLongOr(54321) == 54321);
assert(v_false.asStringOr(test_str) == test_str);
assert(v_false.asStringListOr(test_str_list) == test_str_list);
// Case 2: Long Value
const auto v_long = docopt::value(12345);
assert(v_long.asBoolOr(true) == true);
assert(v_long.asBoolOr(false) == false);
assert(v_long.asLongOr(-1) == 12345); // <-- This should not use the Or-Value
assert(v_long.asLongOr(54321) == 12345); // <-- This should not use the Or-Value
assert(v_long.asStringOr(test_str) == test_str);
assert(v_long.asStringListOr(test_str_list) == test_str_list);
// Case 3: String (Non-Numeric)
const auto v_str = docopt::value(test_other_str);
assert(v_str.asBoolOr(true) == true);
assert(v_str.asBoolOr(false) == false);
assert(v_str.asLongOr(-1) == -1);
assert(v_str.asLongOr(54321) == 54321);
assert(v_str.asStringOr(test_str) == test_other_str); // <-- This should not use the Or-Value
assert(v_str.asStringListOr(test_str_list) == test_str_list);
// Case 4: String (Numeric)
const auto v_num_str = docopt::value(test_num_str);
assert(v_num_str.asBoolOr(true) == true);
assert(v_num_str.asBoolOr(false) == false);
assert(v_num_str.asLongOr(-1) == 123); // <-- This should not use the Or-Value
assert(v_num_str.asLongOr(54321) == 123); // <-- This should not use the Or-Value
assert(v_num_str.asStringOr(test_str) == test_num_str); // <-- This should not use the Or-Value
assert(v_num_str.asStringListOr(test_str_list) == test_str_list);
// Case 5: String List
const auto v_str_list = docopt::value(test_other_str_list);
assert(v_str_list.asBoolOr(true) == true);
assert(v_str_list.asBoolOr(false) == false);
assert(v_str_list.asLongOr(-1) == -1);
assert(v_str_list.asLongOr(54321) == 54321);
assert(v_str_list.asStringOr(test_str) == test_other_str);
assert(v_str_list.asStringListOr(test_str_list) == test_other_str_list); // <-- This should not use the Or-Value