25 #ifndef CXXOPTS_HPP_INCLUDED 26 #define CXXOPTS_HPP_INCLUDED 37 #include <unordered_map> 38 #include <unordered_set> 42 #ifdef __cpp_lib_optional 44 #define CXXOPTS_HAS_OPTIONAL 47 #define CXXOPTS__VERSION_MAJOR 2 48 #define CXXOPTS__VERSION_MINOR 2 49 #define CXXOPTS__VERSION_PATCH 0 63 #ifdef CXXOPTS_USE_UNICODE 64 #include <unicode/unistr.h> 67 typedef icu::UnicodeString
String;
71 class UnicodeStringIterator :
public std::iterator<std::forward_iterator_tag, int32_t> {
73 UnicodeStringIterator(
const icu::UnicodeString*
string, int32_t
pos) :
s(
string),
i(
pos) {}
77 bool operator==(
const UnicodeStringIterator& rhs)
const {
return s == rhs.s &&
i == rhs.i; }
79 bool operator!=(
const UnicodeStringIterator& rhs)
const {
return !(*
this == rhs); }
86 UnicodeStringIterator
operator+(int32_t
v) {
return UnicodeStringIterator(
s,
i +
v); }
89 const icu::UnicodeString*
s;
96 for (
int i = 0;
i !=
n; ++
i) {
103 template <
typename Iterator>
105 while (begin != end) {
126 inline cxxopts::UnicodeStringIterator
begin(
const icu::UnicodeString&
s) {
127 return cxxopts::UnicodeStringIterator(&
s, 0);
130 inline cxxopts::UnicodeStringIterator
end(
const icu::UnicodeString&
s) {
131 return cxxopts::UnicodeStringIterator(&
s,
s.length());
141 template <
typename T>
143 return std::forward<T>(
t);
152 template <
typename Iterator>
154 return s.append(begin, end);
157 template <
typename T>
159 return std::forward<T>(
t);
179 class Value :
public std::enable_shared_from_this<Value> {
181 virtual ~Value() =
default;
183 virtual std::shared_ptr<Value>
clone()
const = 0;
187 virtual void parse()
const = 0;
266 LQUOTE +
arg + RQUOTE +
" given") {}
289 std::basic_regex<char> integer_pattern(
"(-)?(0x)?([0-9a-zA-Z]+)|((0x)?0)");
290 std::basic_regex<char> truthy_pattern(
"(t|T)(rue)?");
291 std::basic_regex<char> falsy_pattern(
"((f|F)(alse)?)?");
295 template <
typename T,
bool B>
298 template <
typename T>
300 template <
typename U>
314 template <
typename T>
316 template <
typename U>
320 template <
typename T,
typename U>
326 template <
typename R,
typename T>
331 return -
static_cast<R>(
t);
334 template <
typename R,
typename T>
339 template <
typename T>
342 std::regex_match(
text, match, integer_pattern);
344 if (match.length() == 0) {
348 if (match.length(4) > 0) {
356 constexpr bool is_signed = std::numeric_limits<T>::is_signed;
357 const bool negative = match.length(1) > 0;
358 const uint8_t
base = match.length(2) > 0 ? 16 : 10;
360 auto value_match = match[3];
364 for (
auto iter = value_match.first; iter != value_match.second; ++iter) {
367 if (*iter >=
'0' && *iter <=
'9') {
369 }
else if (
base == 16 && *iter >=
'a' && *iter <=
'f') {
370 digit = *iter -
'a' + 10;
371 }
else if (
base == 16 && *iter >=
'A' && *iter <=
'F') {
372 digit = *iter -
'A' + 10;
384 detail::check_signed_range<T>(negative,
result,
text);
387 value = checked_negate<T>(
result,
text, std::integral_constant<bool, is_signed>());
393 template <
typename T>
395 std::stringstream
in(
text);
420 std::regex_match(
text,
result, truthy_pattern);
427 std::regex_match(
text,
result, falsy_pattern);
441 template <
typename T>
446 template <
typename T>
453 #ifdef CXXOPTS_HAS_OPTIONAL 454 template <
typename T>
462 template <
typename T>
467 template <
typename T>
472 template <
typename T>
510 return shared_from_this();
516 return shared_from_this();
525 const T&
get()
const {
544 template <
typename T>
549 std::shared_ptr<Value>
clone()
const {
return std::make_shared<Standard_value<T>>(*this); }
561 std::shared_ptr<Value>
clone()
const {
return std::make_shared<Standard_value<bool>>(*this); }
573 template <
typename T>
575 return std::make_shared<values::Standard_value<T>>();
578 template <
typename T>
580 return std::make_shared<values::Standard_value<T>>(&
t);
590 std::shared_ptr<const Value>
val)
651 template <
typename T>
654 throw std::domain_error(
"No value");
657 #ifdef CXXOPTS_NO_RTTI 683 template <
typename T>
698 std::vector<std::string>,
699 bool allow_unrecognised,
709 auto riter =
m_results.find(iter->second);
711 return riter->second.count();
721 auto riter =
m_results.find(iter->second);
723 return riter->second;
742 const std::shared_ptr<std::unordered_map<std::string, std::shared_ptr<OptionDetails>>>
m_options;
754 typedef std::unordered_map<std::string, std::shared_ptr<OptionDetails>>
OptionMap;
795 std::shared_ptr<const Value>
value,
805 template <
typename Iterator>
812 const std::vector<std::string>
groups()
const;
838 std::map<std::string, HelpGroupDetails>
m_help;
847 std::shared_ptr<const Value>
value = ::cxxopts::value<bool>(),
859 std::basic_regex<char> option_matcher(
"--([[:alnum:]][-_[:alnum:]]+)(=(.*))?|-([[:alnum:]]+)");
861 std::basic_regex<char> option_specifier(
"(([[:alnum:]]),)?[ ]*([[:alnum:]][-_[:alnum:]]*)?");
882 if (
o.has_implicit) {
892 String format_description(
const HelpOptionDetails&
o,
size_t start,
size_t width) {
895 if (
o.has_default && (!
o.is_boolean ||
o.default_value !=
"false")) {
901 auto current = std::begin(
desc);
902 auto startLine = current;
903 auto lastSpace = current;
905 auto size =
size_t{};
907 while (current != std::end(
desc)) {
908 if (*current ==
' ') {
912 if (*current ==
'\n') {
913 startLine = current + 1;
914 lastSpace = startLine;
915 }
else if (size >
width) {
916 if (lastSpace == startLine) {
920 startLine = current + 1;
921 lastSpace = startLine;
926 startLine = lastSpace + 1;
944 const std::shared_ptr<std::unordered_map<
std::string, std::shared_ptr<OptionDetails>>>
options,
945 std::vector<std::string> positional,
946 bool allow_unrecognised,
950 m_positional(
std::
move(positional)),
951 m_next_positional(m_positional.begin()),
952 m_allow_unrecognised(allow_unrecognised) {
960 std::shared_ptr<const Value>
value,
962 std::match_results<const char*>
result;
963 std::regex_match(
opts.c_str(),
result, option_specifier);
969 const auto& short_match =
result[2];
970 const auto& long_match =
result[3];
972 if (!short_match.length() && !long_match.length()) {
974 }
else if (long_match.length() == 1 && short_match.length()) {
978 auto option_names = [](
const std::sub_match<const char*>& short_,
const std::sub_match<const char*>& long_) {
979 if (long_.length() == 1) {
980 return std::make_tuple(long_.str(), short_.str());
982 return std::make_tuple(short_.str(), long_.str());
984 }(short_match, long_match);
1007 if (current + 1 >=
argc) {
1008 if (
value->value().has_implicit()) {
1014 if (
value->value().has_implicit()) {
1038 if (!iter->second->value().is_container()) {
1039 if (
result.count() == 0) {
1083 bool consume_remaining =
false;
1085 while (current !=
argc) {
1086 if (strcmp(
argv[current],
"--") == 0) {
1087 consume_remaining =
true;
1092 std::match_results<const char*>
result;
1093 std::regex_match(
argv[current],
result, option_matcher);
1099 if (
argv[current][0] ==
'-' &&
argv[current][1] !=
'\0') {
1113 if (
result[4].length() != 0) {
1116 for (std::size_t
i = 0;
i !=
s.size(); ++
i) {
1129 auto value = iter->second;
1131 if (
i + 1 ==
s.size()) {
1134 }
else if (
value->value().has_implicit()) {
1141 }
else if (
result[1].length() != 0) {
1159 auto opt = iter->second;
1162 if (
result[2].length() != 0) {
1182 if (!store.count() &&
value.has_default()) {
1187 if (consume_remaining) {
1188 while (current <
argc) {
1196 while (current !=
argc) {
1210 std::shared_ptr<const Value>
value,
1213 auto option = std::make_shared<OptionDetails>(
s,
l, stringDesc,
value);
1229 value->has_default(),
1230 value->get_default_value(),
1231 value->has_implicit(),
1232 value->get_implicit_value(),
1234 value->is_container(),
1235 value->is_boolean()});
1247 typedef std::vector<std::pair<String, String>> OptionHelp;
1264 for (
const auto&
o :
group->second.options) {
1269 auto s = format_option(
o);
1274 longest = (
std::min)(longest, static_cast<size_t>(OPTION_LONGEST));
1277 auto allowed =
size_t{76} - longest - OPTION_DESC_GAP;
1279 auto fiter =
format.begin();
1280 for (
const auto&
o :
group->second.options) {
1285 auto d = format_description(
o, longest + OPTION_DESC_GAP, allowed);
1304 for (
size_t i = 0;
i != print_groups.size(); ++
i) {
1306 if (
empty(group_help_text)) {
1309 result += group_help_text;
1310 if (
i < print_groups.size() - 1) {
1317 std::vector<std::string> all_groups;
1318 all_groups.reserve(
m_help.size());
1321 all_groups.push_back(
group.first);
1336 if (help_groups.size() == 0) {
1346 std::vector<std::string>
g;
1350 std::back_inserter(
g),
1360 #endif //CXXOPTS_HPP_INCLUDED bool has_implicit() const
void checked_parse_arg(int argc, char *argv[], int ¤t, std::shared_ptr< OptionDetails > value, const std::string &name)
static constexpr struct cxxopts::@964 version
std::string implicit_value
bool consume_positional(std::string a)
std::vector< std::string >::iterator m_next_positional
std::vector< std::string > m_positional
void parse_default(std::shared_ptr< const OptionDetails > details)
OptionParseException(const std::string &message)
KeyValue(std::string key_, std::string value_)
void operator()(bool negative, U u, const std::string &text)
virtual bool has_implicit() const =0
Option_not_exists_exception(const std::string &option)
#define CXXOPTS__VERSION_MAJOR
void stringstream_parser(const std::string &text, T &value)
Option_required_exception(const std::string &option)
OptionAdder add_options(std::string group="")
std::string m_custom_help
virtual bool is_container() const =0
std::shared_ptr< Value > default_value(const std::string &value)
MatrixMeschach operator+(const MatrixMeschach &mat1, const MatrixMeschach &mat2)
std::shared_ptr< T > m_result
Options & show_positional_help()
std::string help(const std::vector< std::string > &groups={}) const
void parse(int &argc, char **&argv)
const std::string & key() const
std::string m_default_value
std::map< std::string, HelpGroupDetails > m_help
constexpr Process operator++(Process p)
std::shared_ptr< Value > make_storage() const
Missing_argument_exception(const std::string &option)
void add_to_option(const std::string &option, const std::string &arg)
void integer_parser(const std::string &text, T &value)
#define CXXOPTS__VERSION_MINOR
Options & allow_unrecognised_options()
void parse_default(std::shared_ptr< OptionDetails > details)
std::shared_ptr< const Value > m_value
std::shared_ptr< Value > implicit_value(const std::string &value)
Options & positional_help(std::string help_text)
std::shared_ptr< Value > clone() const
std::unordered_map< std::shared_ptr< OptionDetails >, OptionValue > m_results
virtual std::shared_ptr< Value > default_value(const std::string &value)=0
String help_one_group(const std::string &group) const
bool m_allow_unrecognised
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
const Value & value() const
void operator()(bool, U, const std::string &)
void parse_value(const std::string &text, uint8_t &value)
OptionException(const std::string &message)
OptionDetails(const OptionDetails &rhs)
void add_option(const std::string &group, const std::string &s, const std::string &l, std::string desc, std::shared_ptr< const Value > value, std::string arg_help)
std::vector< KeyValue > m_sequential
const std::vector< std::string > groups() const
std::string get_default_value() const
bool m_allow_unrecognised
virtual std::string get_default_value() const =0
bool empty(const std::string &s)
void set_default_and_implicit()
Container::value_type value_type
void generate_all_groups_help(String &result) const
virtual const char * what() const noexcept
ParseResult(const std::shared_ptr< std::unordered_map< std::string, std::shared_ptr< OptionDetails >>>, std::vector< std::string >, bool allow_unrecognised, int &, char **&)
ParseResult parse(int &argc, char **&argv)
bool operator==(const QGLikelihoodParameters &lhs, const QGLikelihoodCategory &rhs)
Test if parameters are compatible with category.
std::shared_ptr< Value > value()
const String & description() const
void check_signed_range(bool negative, U value, const std::string &text)
std::vector< std::string >::iterator m_next_positional
std::shared_ptr< Value > clone() const
const std::vector< KeyValue > & arguments() const
std::string default_value
virtual bool has_default() const =0
void parse_positional(Iterator begin, Iterator end)
Option_requires_argument_exception(const std::string &option)
void add_one_option(const std::string &option, std::shared_ptr< OptionDetails > details)
virtual std::shared_ptr< Value > clone() const =0
bool operator!=(DTCELinkId const &lhs, DTCELinkId const &rhs)
const std::shared_ptr< std::unordered_map< std::string, std::shared_ptr< OptionDetails > > > m_options
Option_not_present_exception(const std::string &option)
unsigned long long uint64_t
std::unordered_set< std::string > m_positional_set
virtual std::shared_ptr< Value > implicit_value(const std::string &value)=0
std::unordered_set< std::string > m_positional_set
bool is_container() const
void parse_option(std::shared_ptr< OptionDetails > value, const std::string &name, const std::string &arg="")
std::vector< HelpOptionDetails > options
size_t stringLength(const String &s)
#define CXXOPTS__VERSION_PATCH
std::unordered_map< std::string, std::shared_ptr< OptionDetails > > OptionMap
std::shared_ptr< Value > value(T &t)
void generate_group_help(String &result, const std::vector< std::string > &groups) const
String & stringAppend(String &s, String a)
std::string get_implicit_value() const
std::string m_positional_help
OptionAdder(Options &options, std::string group)
const std::string & short_name() const
const std::string & value() const
Options & custom_help(std::string help_text)
std::string toUTF8String(T &&t)
size_t count(const std::string &o) const
OptionSpecException(const std::string &message)
Options(std::string program, std::string help_string="")
std::string m_implicit_value
OptionDetails(const std::string &short_, const std::string &long_, const String &desc, std::shared_ptr< const Value > val)
void parse_positional(std::string option)
Argument_incorrect_type(const std::string &arg)
Option_exists_error(const std::string &option)
MatrixMeschach operator*(const MatrixMeschach &mat1, const MatrixMeschach &mat2)
void parse(const std::string &text) const
void parse(std::shared_ptr< const OptionDetails > details, const std::string &text)
Option_not_has_argument_exception(const std::string &option, const std::string &arg)
const OptionValue & operator[](const std::string &option) const
const HelpGroupDetails & group_help(const std::string &group) const
virtual std::string get_implicit_value() const =0
void ensure_value(std::shared_ptr< const OptionDetails > details)
std::shared_ptr< OptionMap > m_options
virtual ~Abstract_value()=default
Abstract_value(const Abstract_value &rhs)
OptionAdder & operator()(const std::string &opts, const std::string &desc, std::shared_ptr< const Value > value=::cxxopts::value< bool >(), std::string arg_help="")
std::shared_ptr< Value > m_value
Option_syntax_exception(const std::string &text)
virtual bool is_boolean() const =0
R checked_negate(T &&t, const std::string &, std::true_type)
virtual void parse() const =0
const std::string & long_name() const
std::vector< std::string > m_positional