37 #include <type_traits>
39 #include <boost/program_options/parsers.hpp>
40 #include <boost/program_options/options_description.hpp>
41 #include <boost/program_options/variables_map.hpp>
42 #include "include_base_utils.h"
48 bool is_yes(
const std::string& str);
50 bool is_no(
const std::string& str);
52 template<
typename T,
bool required = false,
bool dependent = false,
int NUM_DEPS = 1>
78 static_assert(!std::is_same<T, bool>::value,
"Boolean switch can't be required");
97 std::function<
T(
bool,
bool,
T)>
depf;
102 template<
typename T,
int NUM_DEPS>
112 std::array<const arg_descriptor<bool, false> *, NUM_DEPS>
ref;
113 std::function<
T(std::array<bool, NUM_DEPS>,
bool,
T)>
depf;
121 return boost::program_options::value<T>()->required();
127 auto semantic = boost::program_options::value<T>();
136 auto semantic = boost::program_options::value<T>();
138 std::ostringstream format;
141 << arg.
ref.name <<
"'";
142 semantic->default_value(arg.
depf(arg.
ref.default_value,
true, arg.
default_value), format.str());
147 template<
typename T,
int NUM_DEPS>
150 auto semantic = boost::program_options::value<T>();
152 std::array<bool, NUM_DEPS> depval;
154 std::ostringstream format;
156 for (
size_t i = 0; i < depval.size(); ++i)
160 format <<
", " << arg.
depf(depval,
true, arg.
default_value) <<
" if '" << arg.
ref[i]->name <<
"'";
162 for (
size_t i = 0; i < depval.size(); ++i)
163 depval[i] = arg.
ref[i]->default_value;
164 semantic->default_value(arg.
depf(depval,
true, arg.
default_value), format.str());
172 auto semantic = boost::program_options::value<T>();
174 semantic->default_value(def);
181 auto semantic = boost::program_options::value< std::vector<T> >();
182 semantic->default_value(std::vector<T>(),
"");
186 template<
typename T,
bool required,
bool dependent,
int NUM_DEPS>
189 if (0 != description.find_nothrow(arg.name,
false))
191 CHECK_AND_ASSERT_MES(!unique,
void(),
"Argument already exists: " << arg.name);
195 description.add_options()(arg.name,
make_semantic(arg), arg.description);
201 if (0 != description.find_nothrow(arg.
name,
false))
203 CHECK_AND_ASSERT_MES(!unique,
void(),
"Argument already exists: " << arg.
name);
213 if (0 != description.find_nothrow(arg.name,
false))
215 CHECK_AND_ASSERT_MES(!unique,
void(),
"Argument already exists: " << arg.name);
219 description.add_options()(arg.name, boost::program_options::bool_switch(), arg.description);
222 template<
typename charT>
223 boost::program_options::basic_parsed_options<charT>
parse_command_line(
int argc,
const charT*
const argv[],
224 const boost::program_options::options_description& desc,
bool allow_unregistered =
false)
226 auto parser = boost::program_options::command_line_parser(argc, argv);
228 if (allow_unregistered)
230 parser.allow_unregistered();
242 catch (
const std::exception& e)
244 std::cerr <<
"Failed to parse arguments: " << e.what() << std::endl;
245 std::cerr << desc << std::endl;
250 std::cerr <<
"Failed to parse arguments: unknown exception" << std::endl;
251 std::cerr << desc << std::endl;
256 template<
typename T,
bool required,
bool dependent,
int NUM_DEPS>
259 auto value = vm[arg.name];
260 return !value.empty();
263 template<
typename T,
bool required,
bool dependent,
int NUM_DEPS>
266 return vm[arg.name].defaulted();
275 template<
typename T,
int NUM_DEPS>
278 std::array<bool, NUM_DEPS> depval;
279 for (
size_t i = 0; i < depval.size(); ++i)
284 template<
typename T,
bool required>
287 return vm[arg.name].template as<T>();
290 template<
bool dependent,
int NUM_DEPS>
297 extern const arg_descriptor<bool>
arg_help;