gpt4 book ai didi

c++ - 使用 Boost program_options 指定级别(例如 --verbose)

转载 作者:太空狗 更新时间:2023-10-29 23:06:01 25 4
gpt4 key购买 nike

我的一些选项有多个级别,例如“冗长”。我希望我的用户在以下两种等效样式之间进行选择:

// no argument: verbosity of 1
my_program -v

// count the 'v's: verbosity of 4
my_program -vv --something_else XYZ -vv

// specify the value: verbosity of 4
my_program --verbose 3

使用 Boost program_options 库执行此操作的最简单方法是什么?

最佳答案

这就是我设想的代码使用方式。

  1. 我们使用 level_value代替正常的 program_options::value
  2. 通过 option_level<CHAR>(your_value)其中 CHAR是短选项字母,your_value是可选级别,例如冗长,正在提供

例子

#include <boost/program_options.hpp>
using namespace boost;
using namespace boost::program_options;

int main()
{
unsigned verbosity = 0U;
unsigned something_else = 0U;

options_description desc("options");
desc.add_options()
("verbose,v",
level_value(option_level<'v'>(&verbosity)),
"Print more verbose messages at each additional verbosity level.")
("something_else,s",
value<unsigned>(&something_else);

return 0;
}

行为

# verbosity = 7
test_options -vvvvv --something_else 5 -vv

# final verbosity of 3 overrides
test_options -vvvvv --something_else 5 -v 7 -v 3

# no argument always increments: verbosity = 6
test_options -v 3 --verbose 5 -v

实现

我们需要一些东西来保持水平:

//________________________________________________________________________________________

// t_option_level

//________________________________________________________________________________________
struct t_option_level {
public:
unsigned n;
explicit t_option_level(unsigned n_ = 0):n(n_){}
t_option_level& inc(unsigned by = 1){n += by; return *this;}
t_option_level& set(unsigned val){n = val; return *this;}
};

template <typename U>
inline t_option_level* option_level(U* u)
{return reinterpret_cast<t_option_level*>(u);}

递增或设置值的逻辑存在于验证器中:

#include <boost/program_options.hpp>
#include <boost/program_options/options_description.hpp>
//________________________________________________________________________________________
//
// validate
//________________________________________________________________________________________
template <unsigned SHORT_NAME>
void validate(boost::any& v,
const std::vector<std::string>& values,
t_option_level<SHORT_NAME>* /*target_type*/, int)
{
using namespace boost::program_options;

//
// Get the current value
//
t_option_level<SHORT_NAME> i;
if (!v.empty())
i = boost::any_cast<t_option_level<SHORT_NAME>>(v);

//
// Extract any arguments
//
const std::string& s = validators::get_single_string(values, true);
if (s.empty())
{
v = boost::any(i.inc());
return;
}

char short_name = SHORT_NAME;
// multiple 'values's
if (s == std::string(s.length(), short_name))
{
v = boost::any(i.inc(s.length() + 1));
return;
}

// match number
boost::regex r("^(\\d+)$");

// Do regex match and convert the interesting part to
// int.
boost::smatch what;
if (regex_match(s, what, r))
{
v = boost::any(i.set(boost::lexical_cast<unsigned>(s)));
return;
}
else
{
throw validation_error(validation_error::invalid_option_value, "\"" + s + "\" is not a valid argument.");
}

}

这提供了 program_options::value_semantic重写以允许零个或一个参数:

template<class T, class charT = char>
class t_level_value : public boost::program_options::typed_value<T, charT>
{
public:
/** Ctor. The 'store_to' parameter tells where to store
the value when it's known. The parameter can be NULL. */
t_level_value(T* store_to)
: boost::program_options::typed_value<T, charT>(store_to)
{}
unsigned min_tokens() const
{
return 0;
}

unsigned max_tokens() const
{
return 1;
}
};

template<class T>
t_level_value<T>*
level_value(T* v)
{
return new t_level_value<T>(v);
}

关于c++ - 使用 Boost program_options 指定级别(例如 --verbose),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17093579/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com