mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-04-30 12:43:52 +00:00
Adding make_* options
This commit is contained in:
parent
074d0339a4
commit
324a9c738d
128
include/CLI.hpp
128
include/CLI.hpp
@ -11,7 +11,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <unordered_set>
|
#include <set>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
@ -450,6 +450,10 @@ public:
|
|||||||
logit(subcommands.back()->name);
|
logit(subcommands.back()->name);
|
||||||
return subcommands.back().get();
|
return subcommands.back().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------ ADD STYLE ---------//
|
||||||
|
|
||||||
/// Add an option, will automatically understand the type for common types.
|
/// Add an option, will automatically understand the type for common types.
|
||||||
/** To use, create a variable with the expected type, and pass it in after the name.
|
/** To use, create a variable with the expected type, and pass it in after the name.
|
||||||
* After start is called, you can use count to see if the value was passed, and
|
* After start is called, you can use count to see if the value was passed, and
|
||||||
@ -563,7 +567,7 @@ public:
|
|||||||
Option* add_set(
|
Option* add_set(
|
||||||
std::string name, ///< The name, short,long
|
std::string name, ///< The name, short,long
|
||||||
T &member, ///< The selected member of the set
|
T &member, ///< The selected member of the set
|
||||||
std::unordered_set<T> options, ///< The set of posibilities
|
std::set<T> options, ///< The set of posibilities
|
||||||
std::string discription="", ///< Discription string
|
std::string discription="", ///< Discription string
|
||||||
Combiner opts=VALIDATORS ///< The options (REQUIRED, DEFAULT, POSITIONAL, ARGS())
|
Combiner opts=VALIDATORS ///< The options (REQUIRED, DEFAULT, POSITIONAL, ARGS())
|
||||||
) {
|
) {
|
||||||
@ -581,14 +585,20 @@ public:
|
|||||||
bool retval = lexical_cast(res[0][0], member);
|
bool retval = lexical_cast(res[0][0], member);
|
||||||
if(!retval)
|
if(!retval)
|
||||||
return false;
|
return false;
|
||||||
return std::find(std::begin(options), std::end(options), retval) != std::end(options);
|
return std::find(std::begin(options), std::end(options), member) != std::end(options);
|
||||||
};
|
};
|
||||||
|
|
||||||
return add_option(name, fun, discription, opts);
|
return add_option(name, fun, discription, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------ MAKE STYLE ---------//
|
||||||
|
|
||||||
/// Prototype for new output style
|
/// Prototype for new output style
|
||||||
template<typename T = std::string>
|
template<typename T = std::string,
|
||||||
|
enable_if_t<!std::is_array<T>::value, detail::enabler> = dummy>
|
||||||
Value<T> make_option(
|
Value<T> make_option(
|
||||||
std::string name, ///< The name, short,long
|
std::string name, ///< The name, short,long
|
||||||
std::string discription="",
|
std::string discription="",
|
||||||
@ -611,7 +621,117 @@ public:
|
|||||||
add_option(name, fun, discription, opts);
|
add_option(name, fun, discription, opts);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prototype for new output style with default
|
||||||
|
template<typename T = std::string,
|
||||||
|
enable_if_t<!std::is_array<T>::value, detail::enabler> = dummy>
|
||||||
|
Value<T> make_option(
|
||||||
|
std::string name, ///< The name, short,long
|
||||||
|
const T& default_value,
|
||||||
|
std::string discription="",
|
||||||
|
Combiner opts=VALIDATORS
|
||||||
|
) {
|
||||||
|
|
||||||
|
Value<T> out(name);
|
||||||
|
std::shared_ptr<std::unique_ptr<T>> ptr = out.value;
|
||||||
|
ptr->reset(new T(default_value)); // resets the internal ptr
|
||||||
|
|
||||||
|
CLI::callback_t fun = [ptr](CLI::results_t res){
|
||||||
|
if(res.size()!=1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(res[0].size()!=1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ptr->reset(new T()); // resets the internal ptr
|
||||||
|
return lexical_cast(res[0][0], **ptr);
|
||||||
|
};
|
||||||
|
add_option(name, fun, discription, opts);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prototype for new output style
|
||||||
|
template<typename T>
|
||||||
|
Value<std::vector<T>> make_option(
|
||||||
|
std::string name, ///< The name, short,long
|
||||||
|
std::string discription="",
|
||||||
|
Combiner opts=VALIDATORS
|
||||||
|
) {
|
||||||
|
|
||||||
|
if(opts.num==0)
|
||||||
|
throw IncorrectConstruction("Must have ARGS or be a vector.");
|
||||||
|
|
||||||
|
Value<std::vector<T>> out(name);
|
||||||
|
std::shared_ptr<std::unique_ptr<std::vector<T> >> ptr = out.value;
|
||||||
|
|
||||||
|
CLI::callback_t fun = [ptr](CLI::results_t res){
|
||||||
|
ptr->reset(new std::vector<T>()); // resets the internal ptr
|
||||||
|
bool retval = true;
|
||||||
|
for(const auto &a : res)
|
||||||
|
for(const auto &b : a) {
|
||||||
|
(*ptr)->emplace_back();
|
||||||
|
retval &= lexical_cast(b, (*ptr)->back());
|
||||||
|
}
|
||||||
|
return (*ptr)->size() > 0 && retval;
|
||||||
|
};
|
||||||
|
add_option(name, fun, discription, opts);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Prototype for new output style: flag
|
||||||
|
Value<int> make_flag(
|
||||||
|
std::string name, ///< The name, short,long
|
||||||
|
std::string discription=""
|
||||||
|
) {
|
||||||
|
|
||||||
|
Value<int> out(name);
|
||||||
|
std::shared_ptr<std::unique_ptr<int>> ptr = out.value;
|
||||||
|
ptr->reset(new int()); // resets the internal ptr
|
||||||
|
**ptr = 0;
|
||||||
|
|
||||||
|
CLI::callback_t fun = [ptr](CLI::results_t res){
|
||||||
|
**ptr = (int) res.size();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
add_option(name, fun, discription, NOTHING);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add set of options
|
||||||
|
template<typename T>
|
||||||
|
Value<T> make_set(
|
||||||
|
std::string name, ///< The name, short,long
|
||||||
|
std::set<T> options, ///< The set of posibilities
|
||||||
|
std::string discription="", ///< Discription string
|
||||||
|
Combiner opts=VALIDATORS ///< The options (REQUIRED, DEFAULT, POSITIONAL, ARGS())
|
||||||
|
) {
|
||||||
|
|
||||||
|
Value<T> out(name);
|
||||||
|
std::shared_ptr<std::unique_ptr<T>> ptr = out.value;
|
||||||
|
|
||||||
|
if(opts.num!=1)
|
||||||
|
throw IncorrectConstruction("Must have ARGS(1).");
|
||||||
|
|
||||||
|
CLI::callback_t fun = [ptr, options](CLI::results_t res){
|
||||||
|
if(res.size()!=1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(res[0].size()!=1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ptr->reset(new T());
|
||||||
|
bool retval = lexical_cast(res[0][0], **ptr);
|
||||||
|
if(!retval)
|
||||||
|
return false;
|
||||||
|
return std::find(std::begin(options), std::end(options), **ptr) != std::end(options);
|
||||||
|
};
|
||||||
|
|
||||||
|
add_option(name, fun, discription, opts);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Parses the command line - throws errors
|
/// Parses the command line - throws errors
|
||||||
void parse(int argc, char **argv) {
|
void parse(int argc, char **argv) {
|
||||||
|
@ -249,6 +249,22 @@ TEST_F(TApp, FileExists) {
|
|||||||
EXPECT_FALSE(CLI::_ExistingFile(myfile));
|
EXPECT_FALSE(CLI::_ExistingFile(myfile));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(TApp, InSet) {
|
||||||
|
|
||||||
|
std::string choice;
|
||||||
|
app.add_set("q,quick", choice, {"one", "two", "three"});
|
||||||
|
|
||||||
|
args = {"--quick", "two"};
|
||||||
|
|
||||||
|
EXPECT_NO_THROW(run());
|
||||||
|
EXPECT_EQ("two", choice);
|
||||||
|
|
||||||
|
app.reset();
|
||||||
|
|
||||||
|
args = {"--quick", "four"};
|
||||||
|
EXPECT_THROW(run(), CLI::ParseError);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(TApp, VectorFixedString) {
|
TEST_F(TApp, VectorFixedString) {
|
||||||
std::vector<std::string> strvec;
|
std::vector<std::string> strvec;
|
||||||
std::vector<std::string> answer{"mystring", "mystring2", "mystring3"};
|
std::vector<std::string> answer{"mystring", "mystring2", "mystring3"};
|
||||||
@ -366,7 +382,6 @@ TEST_F(TAppValue, OneString) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add vector arguments
|
|
||||||
// TODO: Maybe add function to call on subcommand parse? Stashed.
|
// TODO: Maybe add function to call on subcommand parse? Stashed.
|
||||||
// TODO: Check help output
|
// TODO: Check help output
|
||||||
// TODO: Add default/type info to help
|
// TODO: Add default/type info to help
|
||||||
|
Loading…
x
Reference in New Issue
Block a user