19 #include <unordered_map> 20 #include <unordered_set> 22 #include <boost/version.hpp> 23 #include <glog/logging.h> 46 explicit GFlagInfo(gflags::CommandLineFlagInfo
info)
54 auto strValue = folly::to<std::string>(
value);
56 gflags::SetCommandLineOption(
info_.name.c_str(), strValue.c_str());
58 throw po::invalid_option_value(strValue);
65 CHECK(gflags::GetCommandLineOption(
info_.name.c_str(), &str));
66 return folly::to<T>(str);
69 const gflags::CommandLineFlagInfo&
info()
const {
74 gflags::CommandLineFlagInfo
info_;
79 class GFlagValueSemanticBase :
public po::value_semantic {
81 explicit GFlagValueSemanticBase(std::shared_ptr<GFlagInfo<T>>
info)
87 #if BOOST_VERSION >= 105900 && BOOST_VERSION <= 106400 88 bool adjacent_tokens_only()
const override {
92 bool is_composing()
const override {
95 bool is_required()
const override {
99 void notify(
const boost::any& )
const override {}
100 bool apply_default(
boost::any& valueStore)
const override {
113 const std::vector<std::string>&
tokens,
114 bool )
const override;
117 virtual T parseValue(
const std::vector<std::string>& tokens)
const = 0;
120 mutable std::shared_ptr<GFlagInfo<T>>
info_;
126 const std::vector<std::string>&
tokens,
130 val = this->parseValue(tokens);
132 }
catch (
const std::exception&) {
133 throw po::invalid_option_value(
136 this->
info_->set(val);
141 class GFlagValueSemantic :
public GFlagValueSemanticBase<T> {
143 explicit GFlagValueSemantic(std::shared_ptr<GFlagInfo<T>>
info)
146 unsigned min_tokens()
const override {
149 unsigned max_tokens()
const override {
153 T parseValue(
const std::vector<std::string>& tokens)
const override {
154 DCHECK(tokens.size() == 1);
155 return folly::to<T>(tokens.front());
159 class BoolGFlagValueSemantic :
public GFlagValueSemanticBase<bool> {
161 explicit BoolGFlagValueSemantic(std::shared_ptr<GFlagInfo<bool>>
info)
164 unsigned min_tokens()
const override {
167 unsigned max_tokens()
const override {
171 bool parseValue(
const std::vector<std::string>& tokens)
const override {
172 DCHECK(tokens.empty());
177 class NegativeBoolGFlagValueSemantic :
public BoolGFlagValueSemantic {
179 explicit NegativeBoolGFlagValueSemantic(std::shared_ptr<GFlagInfo<bool>>
info)
189 static const std::unordered_map<std::string, std::string> gFlagOverrides{
193 auto pos = gFlagOverrides.find(name);
194 return pos != gFlagOverrides.end() ? pos->second :
name;
199 gflags::CommandLineFlagInfo&&
flag,
200 po::options_description& desc,
202 auto gflagInfo = std::make_shared<GFlagInfo<T>>(
std::move(
flag));
203 auto&
info = gflagInfo->info();
204 auto name = getName(info.name);
215 new GFlagValueSemantic<T>(gflagInfo),
216 info.description.c_str());
221 gflags::CommandLineFlagInfo&&
flag,
222 po::options_description& desc,
224 auto gflagInfo = std::make_shared<GFlagInfo<bool>>(
std::move(flag));
225 auto&
info = gflagInfo->info();
226 auto name = getName(info.name);
231 negationPrefix =
"no";
235 negationPrefix =
"no-";
242 new BoolGFlagValueSemantic(gflagInfo),
243 info.description.c_str())
244 ((negationPrefix + name).c_str(),
245 new NegativeBoolGFlagValueSemantic(gflagInfo),
246 folly::to<std::string>(
"(no) ", info.description).c_str());
250 typedef void (*FlagAdder)(
251 gflags::CommandLineFlagInfo&&,
252 po::options_description&,
255 const std::unordered_map<std::string, FlagAdder> gFlagAdders = {
256 #define X(NAME, TYPE) \ 257 { NAME, addGFlag<TYPE> } 271 static const std::unordered_set<std::string> gSkipFlags{
284 "tab_completion_columns",
285 "tab_completion_word",
288 po::options_description desc(
"GFlags");
290 std::vector<gflags::CommandLineFlagInfo> allFlags;
291 gflags::GetAllFlags(&allFlags);
293 for (
auto&
f : allFlags) {
294 if (gSkipFlags.count(
f.name)) {
297 auto pos = gFlagAdders.find(
f.type);
298 CHECK(pos != gFlagAdders.end()) <<
"Invalid flag type: " <<
f.type;
308 po::command_line_parser&&
parser,
309 const po::options_description& desc) {
312 result.
options =
parser.options(desc).allow_unregistered().run();
314 bool setCommand =
true;
315 for (
auto& opt : result.
options.options) {
316 auto&
tokens = opt.original_tokens;
317 auto tokensStart =
tokens.begin();
319 if (setCommand && opt.position_key != -1) {
320 DCHECK(tokensStart !=
tokens.end());
321 result.
command = *(tokensStart++);
324 if (opt.position_key != -1 || opt.unregistered) {
344 const char*
const argv[],
345 const po::options_description& desc) {
346 return doParseNestedCommandLine(po::command_line_parser(argc, argv), desc);
350 const std::vector<std::string>& cmdline,
351 const po::options_description& desc) {
352 return doParseNestedCommandLine(po::command_line_parser(cmdline), desc);
size_t parse(const char *buf, size_t len)
NestedCommandLineParseResult parseNestedCommandLine(int argc, const char *const argv[], const po::options_description &desc)
constexpr detail::Map< Move > move
—— Concurrent Priority Queue Implementation ——
static http_parser * parser
PUSHMI_INLINE_VAR constexpr detail::transform_fn transform
Composed any(Predicate pred=Predicate())
void BENCHFUN() replace(size_t iters, size_t arg)
std::vector< std::string > rest
gflags::CommandLineFlagInfo info_
Optional< std::string > command
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
po::options_description getGFlags(ProgramOptionsStyle style)
static const char tokens[256]
boost::program_options::parsed_options options