35 using namespace Property;
39 namespace boost {
namespace program_options {
42 validators::check_first_occurrence(v);
43 const std::string &s = validators::get_single_string(values);
45 int64_t result = strtoll(s.c_str(), &last, 0);
47 if (s.c_str() == last)
48 throw invalid_option_value(s);
52 case 'K': result *= 1000LL;
break;
54 case 'M': result *= 1000000LL;
break;
56 case 'G': result *= 1000000000LL;
break;
58 default:
throw invalid_option_value(s +
": unknown suffix");
64 validators::check_first_occurrence(v);
65 const std::string &s = validators::get_single_string(values);
67 double result = strtod(s.c_str(), &last);
69 if (s.c_str() == last)
70 throw invalid_option_value(s);
74 case 'K': result *= 1000LL;
break;
76 case 'M': result *= 1000000LL;
break;
78 case 'G': result *= 1000000000LL;
break;
80 default:
throw invalid_option_value(s +
": unknown suffix");
86 validate(v, values, (int64_t *)0, 0);
87 int64_t res = any_cast<int64_t>(v);
89 if (res > INT32_MAX || res < INT32_MIN) {
90 const std::string &s = validators::get_single_string(values);
91 throw invalid_option_value(s +
": number out of range of 32-bit integer");
93 v = any((int32_t)res);
97 validate(v, values, (int64_t *)0, 0);
98 int64_t res = any_cast<int64_t>(v);
100 if (res > UINT16_MAX) {
101 const std::string &s = validators::get_single_string(values);
102 throw invalid_option_value(s +
": number out of range of 16-bit integer");
104 v = any((uint16_t)res);
122 parser.options(full);
125 parser.positional(*p);
127 #if BOOST_VERSION >= 103500
128 if (allow_unregistered)
129 store(parser.allow_unregistered().run(), result);
131 store(parser.run(), result);
133 store(parser.run(), result);
136 catch (std::exception &e) {
145 bool allow_unregistered) {
146 m_need_alias_sync =
true;
149 std::ifstream in(fname.c_str());
154 #if BOOST_VERSION >= 103500
155 parsed_options parsed_opts = parse_config_file(in, desc, allow_unregistered);
156 store(parsed_opts, m_map);
157 for (
size_t i = 0; i < parsed_opts.options.size(); i++) {
158 if (parsed_opts.options[i].unregistered && parsed_opts.options[i].string_key !=
"")
159 m_map.insert(Map::value_type(parsed_opts.options[i].string_key,
160 Value(parsed_opts.options[i].value[0],
false)));
163 store(parse_config_file(in, desc), m_map);
166 catch (std::exception &e) {
174 bool allow_unregistered) {
176 const char *dummy =
"_";
180 argv = (
char **)&dummy;
182 HT_TRY(
"parsing arguments",
183 command_line_parser parser(argc, argv);
184 parse(parser, desc, m_map, hidden, p, allow_unregistered));
191 HT_TRY(
"parsing arguments",
192 command_line_parser parser(args);
193 parse(parser, desc, m_map, hidden, p, allow_unregistered));
200 boost::program_options::notify(m_map);
206 m_alias_map[primary] = secondary;
208 m_alias_map.insert(std::make_pair(primary, secondary));
210 m_need_alias_sync =
true;
214 if (!m_need_alias_sync)
217 for (
const auto &v : m_alias_map) {
218 Map::iterator it1 = m_map.find(v.first);
219 Map::iterator it2 = m_map.find(v.second);
221 if (it1 != m_map.end()) {
222 if (it2 == m_map.end())
223 m_map.insert(std::make_pair(v.second, (*it1).second));
224 else if (!(*it1).second.defaulted())
225 (*it2).second = (*it1).second;
226 else if (!(*it2).second.defaulted())
227 (*it1).second = (*it2).second;
229 else if (it2 != m_map.end()) {
230 m_map.insert(std::make_pair(v.first, (*it2).second));
233 m_need_alias_sync =
false;
238 if (v.type() ==
typeid(
String))
239 return boost::any_cast<
String>(v);
241 if (v.type() ==
typeid(uint16_t))
242 return format(
"%u", (
unsigned)boost::any_cast<uint16_t>(v));
244 if (v.type() ==
typeid(int32_t))
245 return format(
"%d", boost::any_cast<int32_t>(v));
247 if (v.type() ==
typeid(int64_t))
248 return format(
"%llu", (
Llu)boost::any_cast<int64_t>(v));
250 if (v.type() ==
typeid(double))
251 return format(
"%g", boost::any_cast<double>(v));
253 if (v.type() ==
typeid(bool)) {
254 bool bval = boost::any_cast<
bool>(v);
255 return bval ?
"true" :
"false";
257 if (v.type() ==
typeid(
Strings)) {
261 if (v.type() ==
typeid(
Int64s)) {
265 if (v.type() ==
typeid(
Doubles)) {
270 return "invalid option type";
275 for (
const auto &kv : m_map) {
276 bool isdefault = kv.second.defaulted();
278 if (include_default || !isdefault) {
279 out << kv.first <<
'=' << to_str(kv.second.value());
void alias(const String &primary, const String &secondary, bool overwrite=false)
Setup an alias for a property.
std::vector< double > Doubles
void parse_args(int argc, char *argv[], const PropertiesDesc &desc, const PropertiesDesc *hidden=0, const PositionalDesc *p=0, bool allow_unregistered=false)
Parses command line arguments.
static bool allow_unregistered
std::string String
A String is simply a typedef to std::string.
Po::positional_options_description PositionalDesc
String format(const char *fmt,...)
Returns a String using printf like format facilities Vanilla snprintf is about 1.5x faster than this...
Po::typed_value< Int64s > * i64s(Int64s *v=0)
String format_list(const SequenceT &seq, const char *sep=", ")
Return a string presentation of a sequence.
long long unsigned int Llu
Shortcut for printf formats.
Po::typed_value< Doubles > * f64s(Doubles *v=0)
void validate(boost::any &v, const Strings &values,::uint16_t *, int)
Program options handling.
std::vector< String > Strings
std::vector< int64_t > Int64s
void notify()
Calls user-defined notifier functions (if any) with final values.
void print(std::ostream &out, bool include_default=false)
Prints keys and values of the configuration map.
void sync_aliases()
Sync alias values.
Logging routines and macros.
Compatibility Macros for C/C++.
Po::options_description PropertiesDesc
std::vector< std::string > Strings
Po::typed_value< Strings > * strs(Strings *v=0)
static String to_str(const boost::any &a)
Helper to print boost::any used by property values.
#define HT_THROWF(_code_, _fmt_,...)
void load(const String &filename, const PropertiesDesc &desc, bool allow_unregistered=false)
Loads a configuration file with properties.
#define HT_TRY(_s_, _code_)
#define HT_THROW(_code_, _msg_)