3 #include <boost/program_options.hpp> 4 namespace po = boost::program_options;
20 std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec)
22 for (
auto const& item : vec)
30 template std::ostream& std::operator<<<int>(std::ostream&,
const std::vector<int>&);
31 template std::ostream& std::operator<<<char>(std::ostream&,
const std::vector<char>&);
32 template std::ostream& std::operator<<<std::string>(std::ostream&,
const std::vector<std::string>&);
33 template std::ostream& std::operator<<<float>(std::ostream&,
const std::vector<float>&);
34 template std::ostream& std::operator<<<bool>(std::ostream&,
const std::vector<bool>&);
50 virtual bool was_supplied(
const std::string& key)
override;
51 virtual std::string help()
override;
52 virtual void check_unregistered()
override;
53 virtual std::vector<std::shared_ptr<base_option>> get_all_options()
override;
54 virtual std::shared_ptr<base_option> get_option(
const std::string& key)
override;
56 virtual void insert(
const std::string& key,
const std::string& value)
override 58 m_command_line.push_back(
"--" + key);
61 m_command_line.push_back(value);
66 virtual void replace(
const std::string& key,
const std::string& value)
override 68 auto full_key =
"--" + key;
69 auto it =
std::find(m_command_line.begin(), m_command_line.end(), full_key);
72 if (it == m_command_line.end())
79 if (it + 1 == m_command_line.end() || (*(it + 1)).find(
"--") != std::string::npos)
81 THROW(key +
" option does not have a value.");
91 po::positional_options_description p;
92 p.add(key.c_str(), position);
93 po::parsed_options pos = po::command_line_parser(m_command_line)
94 .style(po::command_line_style::default_style ^ po::command_line_style::allow_guessing)
95 .options(master_description)
100 auto it = std::find_if(pos.options.begin(), pos.options.end(),
101 [&key](boost::program_options::option& option) {
return option.string_key == key; });
103 if (it != pos.options.end() && (*it).value.size() > 0)
105 token = (*it).value.at(0);
113 template <
typename T>
114 typename po::typed_value<std::vector<T>>* get_base_boost_value(std::shared_ptr<
typed_option<T>>& opt);
116 template <
typename T>
117 po::typed_value<std::vector<T>>* get_base_boost_value(std::shared_ptr<
typed_option<std::vector<T>>>& opt);
119 template <
typename T>
120 po::typed_value<std::vector<T>>* convert_to_boost_value(std::shared_ptr<
typed_option<T>>& opt);
122 template <
typename T>
123 po::typed_value<std::vector<T>>* convert_to_boost_value(std::shared_ptr<
typed_option<std::vector<T>>>& opt);
125 template <
typename T>
126 po::typed_value<std::vector<T>>* add_notifier(
127 std::shared_ptr<
typed_option<T>>& opt, po::typed_value<std::vector<T>>* po_value);
129 template <
typename T>
130 po::typed_value<std::vector<T>>* add_notifier(
131 std::shared_ptr<
typed_option<std::vector<T>>>& opt, po::typed_value<std::vector<T>>* po_value);
133 template <
typename T>
134 bool add_if_t(std::shared_ptr<base_option> opt, po::options_description& options_description);
136 void add_to_description(std::shared_ptr<base_option> opt, po::options_description& options_description);
138 template <
typename TTypes>
141 if (add_if_t<typename TTypes::head>(opt, options_description))
145 add_to_description_impl<typename TTypes::tail>(opt, options_description);
148 template <
typename T>
149 void add_to_description(std::shared_ptr<
typed_option<T>> opt, po::options_description& options_description);
152 std::map<std::string, std::shared_ptr<base_option>>
m_options;
170 template <
typename T>
171 po::typed_value<std::vector<T>>* options_boost_po::get_base_boost_value(std::shared_ptr<
typed_option<T>>& opt)
173 auto value = po::value<std::vector<T>>();
175 if (opt->default_value_supplied())
177 value->default_value({opt->default_value()});
180 return add_notifier(opt, value)->composing();
183 template <
typename T>
184 po::typed_value<std::vector<T>>* options_boost_po::get_base_boost_value(
187 auto value = po::value<std::vector<T>>();
189 if (opt->default_value_supplied())
191 value->default_value(opt->default_value());
194 return add_notifier(opt, value)->composing();
197 template <
typename T>
198 po::typed_value<std::vector<T>>* options_boost_po::convert_to_boost_value(std::shared_ptr<
typed_option<T>>& opt)
200 return get_base_boost_value(opt);
203 template <
typename T>
204 po::typed_value<std::vector<T>>* options_boost_po::convert_to_boost_value(
207 return get_base_boost_value(opt)->multitoken();
211 po::typed_value<std::vector<bool>>* options_boost_po::convert_to_boost_value(std::shared_ptr<
typed_option<bool>>& opt);
213 template <
typename T>
214 po::typed_value<std::vector<T>>* options_boost_po::add_notifier(
215 std::shared_ptr<
typed_option<T>>& opt, po::typed_value<std::vector<T>>* po_value)
217 return po_value->notifier([opt](std::vector<T> final_arguments) {
218 T first = final_arguments[0];
219 for (
auto const& item : final_arguments)
223 std::stringstream ss;
224 ss <<
"Disagreeing option values for '" << opt->m_name <<
"': '" << first <<
"' vs '" << item <<
"'";
230 opt->m_location = first;
235 template <
typename T>
236 po::typed_value<std::vector<T>>* options_boost_po::add_notifier(
237 std::shared_ptr<
typed_option<std::vector<T>>>& opt, po::typed_value<std::vector<T>>* po_value)
239 return po_value->notifier([opt](std::vector<T> final_arguments) {
241 opt->m_location = final_arguments;
242 opt->value(final_arguments);
246 template <
typename T>
247 bool options_boost_po::add_if_t(std::shared_ptr<base_option> opt, po::options_description& options_description)
249 if (opt->m_type_hash ==
typeid(T).hash_code())
252 add_to_description(typed, options_description);
260 void options_boost_po::add_to_description_impl<typelist<>>(
261 std::shared_ptr<base_option> opt, po::options_description& options_description);
263 template <
typename T>
264 void options_boost_po::add_to_description(
265 std::shared_ptr<
typed_option<T>> opt, po::options_description& options_description)
267 std::string boost_option_name = opt->m_name;
268 if (opt->m_short_name !=
"")
270 boost_option_name +=
",";
271 boost_option_name += opt->m_short_name;
273 options_description.add_options()(boost_option_name.c_str(), convert_to_boost_value(opt), opt->m_help.c_str());
275 if (m_defined_options.count(opt->m_name) == 0)
278 master_description.add_options()(boost_option_name.c_str(), convert_to_boost_value(opt),
"");
#define THROW_EX(ex, args)
std::vector< std::string > m_command_line
bool try_get_positional_option_token(const std::string &key, std::string &token, int position)
void add_to_description_impl(std::shared_ptr< base_option > opt, po::options_description &options_description)
po::options_description master_description
std::set< std::string > m_ignore_supplied
options_boost_po(std::vector< std::string > args)
virtual void insert(const std::string &key, const std::string &value) override
options_boost_po(int argc, char **argv)
std::set< std::string > m_supplied_options
node_pred * find(recall_tree &b, uint32_t cn, example &ec)
std::map< std::string, std::shared_ptr< base_option > > m_options
std::set< std::string > m_defined_options
std::stringstream m_help_stringstream
virtual void replace(const std::string &key, const std::string &value) override