mirror of
https://github.com/KeqingMoe/argparse.git
synced 2025-07-03 22:54:39 +00:00
Rename identifiers
There are no functional changes in this commit. Signed-off-by: Sean Robinson <sean.robinson@scottsdalecc.edu>
This commit is contained in:
parent
985ea8666d
commit
ce3c43eb9b
@ -10,11 +10,12 @@ CheckOptions:
|
|||||||
- { key: readability-identifier-naming.ConstexprVariableCase, value: lower_case }
|
- { key: readability-identifier-naming.ConstexprVariableCase, value: lower_case }
|
||||||
- { key: readability-identifier-naming.ConstexprVariableIgnoredRegexp, value: "^Is.+" }
|
- { key: readability-identifier-naming.ConstexprVariableIgnoredRegexp, value: "^Is.+" }
|
||||||
- { key: readability-identifier-naming.FunctionCase, value: lower_case }
|
- { key: readability-identifier-naming.FunctionCase, value: lower_case }
|
||||||
- { key: readability-identifier-naming.LocalVariableIgnoredRegexp, value: "^[a-z][a-z_]+" }
|
|
||||||
- { key: readability-identifier-naming.NamespaceCase, value: lower_case }
|
- { key: readability-identifier-naming.NamespaceCase, value: lower_case }
|
||||||
- { key: readability-identifier-naming.PrivateMemberPrefix, value: m }
|
- { key: readability-identifier-naming.ParameterCase, value: lower_case }
|
||||||
|
- { key: readability-identifier-naming.PrivateMemberCase, value: lower_case }
|
||||||
|
- { key: readability-identifier-naming.PrivateMemberPrefix, value: m_ }
|
||||||
- { key: readability-identifier-naming.StructCase, value: CamelCase }
|
- { key: readability-identifier-naming.StructCase, value: CamelCase }
|
||||||
- { key: readability-identifier-naming.StructIgnoredRegexp, value: "parse_number" }
|
- { key: readability-identifier-naming.StructIgnoredRegexp, value: "parse_number" }
|
||||||
- { key: readability-identifier-naming.VariableCase, value: camelBack }
|
- { key: readability-identifier-naming.VariableCase, value: lower_case }
|
||||||
|
|
||||||
HeaderFilterRegex: '.*'
|
HeaderFilterRegex: '.*'
|
||||||
|
@ -350,11 +350,11 @@ class Argument {
|
|||||||
template <std::size_t N, std::size_t... I>
|
template <std::size_t N, std::size_t... I>
|
||||||
explicit Argument(std::array<std::string_view, N> &&a,
|
explicit Argument(std::array<std::string_view, N> &&a,
|
||||||
std::index_sequence<I...> unused)
|
std::index_sequence<I...> unused)
|
||||||
: mIsOptional((is_optional(a[I]) || ...)), mIsRequired(false),
|
: m_is_optional((is_optional(a[I]) || ...)), m_is_required(false),
|
||||||
mIsRepeatable(false), mIsUsed(false) {
|
m_is_repeatable(false), m_is_used(false) {
|
||||||
((void)mNames.emplace_back(a[I]), ...);
|
((void)m_names.emplace_back(a[I]), ...);
|
||||||
std::sort(
|
std::sort(
|
||||||
mNames.begin(), mNames.end(), [](const auto &lhs, const auto &rhs) {
|
m_names.begin(), m_names.end(), [](const auto &lhs, const auto &rhs) {
|
||||||
return lhs.size() == rhs.size() ? lhs < rhs : lhs.size() < rhs.size();
|
return lhs.size() == rhs.size() ? lhs < rhs : lhs.size() < rhs.size();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -364,41 +364,41 @@ public:
|
|||||||
explicit Argument(std::array<std::string_view, N> &&a)
|
explicit Argument(std::array<std::string_view, N> &&a)
|
||||||
: Argument(std::move(a), std::make_index_sequence<N>{}) {}
|
: Argument(std::move(a), std::make_index_sequence<N>{}) {}
|
||||||
|
|
||||||
Argument &help(std::string aHelp) {
|
Argument &help(std::string help_text) {
|
||||||
mHelp = std::move(aHelp);
|
m_help = std::move(help_text);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> Argument &default_value(T &&aDefaultValue) {
|
template <typename T> Argument &default_value(T &&value) {
|
||||||
mDefaultValueRepr = details::repr(aDefaultValue);
|
m_default_value_repr = details::repr(value);
|
||||||
mDefaultValue = std::forward<T>(aDefaultValue);
|
m_default_value = std::forward<T>(value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Argument &required() {
|
Argument &required() {
|
||||||
mIsRequired = true;
|
m_is_required = true;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Argument &implicit_value(std::any aImplicitValue) {
|
Argument &implicit_value(std::any value) {
|
||||||
mImplicitValue = std::move(aImplicitValue);
|
m_implicit_value = std::move(value);
|
||||||
mNumArgs = 0;
|
m_num_args = 0;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class F, class... Args>
|
template <class F, class... Args>
|
||||||
auto action(F &&aAction, Args &&...aBound)
|
auto action(F &&callable, Args &&...bound_args)
|
||||||
-> std::enable_if_t<std::is_invocable_v<F, Args..., std::string const>,
|
-> std::enable_if_t<std::is_invocable_v<F, Args..., std::string const>,
|
||||||
Argument &> {
|
Argument &> {
|
||||||
using action_type = std::conditional_t<
|
using action_type = std::conditional_t<
|
||||||
std::is_void_v<std::invoke_result_t<F, Args..., std::string const>>,
|
std::is_void_v<std::invoke_result_t<F, Args..., std::string const>>,
|
||||||
void_action, valued_action>;
|
void_action, valued_action>;
|
||||||
if constexpr (sizeof...(Args) == 0) {
|
if constexpr (sizeof...(Args) == 0) {
|
||||||
mAction.emplace<action_type>(std::forward<F>(aAction));
|
m_action.emplace<action_type>(std::forward<F>(callable));
|
||||||
} else {
|
} else {
|
||||||
mAction.emplace<action_type>(
|
m_action.emplace<action_type>(
|
||||||
[f = std::forward<F>(aAction),
|
[f = std::forward<F>(callable),
|
||||||
tup = std::make_tuple(std::forward<Args>(aBound)...)](
|
tup = std::make_tuple(std::forward<Args>(bound_args)...)](
|
||||||
std::string const &opt) mutable {
|
std::string const &opt) mutable {
|
||||||
return details::apply_plus_one(f, tup, opt);
|
return details::apply_plus_one(f, tup, opt);
|
||||||
});
|
});
|
||||||
@ -407,7 +407,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto &append() {
|
auto &append() {
|
||||||
mIsRepeatable = true;
|
m_is_repeatable = true;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,33 +451,33 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Argument &nargs(int aNumArgs) {
|
Argument &nargs(int num_args) {
|
||||||
if (aNumArgs < 0) {
|
if (num_args < 0) {
|
||||||
throw std::logic_error("Number of arguments must be non-negative");
|
throw std::logic_error("Number of arguments must be non-negative");
|
||||||
}
|
}
|
||||||
mNumArgs = aNumArgs;
|
m_num_args = num_args;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Argument &remaining() {
|
Argument &remaining() {
|
||||||
mNumArgs = -1;
|
m_num_args = -1;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
Iterator consume(Iterator start, Iterator end,
|
Iterator consume(Iterator start, Iterator end,
|
||||||
std::string_view usedName = {}) {
|
std::string_view used_name = {}) {
|
||||||
if (!mIsRepeatable && mIsUsed) {
|
if (!m_is_repeatable && m_is_used) {
|
||||||
throw std::runtime_error("Duplicate argument");
|
throw std::runtime_error("Duplicate argument");
|
||||||
}
|
}
|
||||||
mIsUsed = true;
|
m_is_used = true;
|
||||||
mUsedName = usedName;
|
m_used_name = used_name;
|
||||||
if (mNumArgs == 0) {
|
if (m_num_args == 0) {
|
||||||
mValues.emplace_back(mImplicitValue);
|
m_values.emplace_back(m_implicit_value);
|
||||||
std::visit([](const auto &aAction) { aAction({}); }, mAction);
|
std::visit([](const auto &f) { f({}); }, m_action);
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
if (mNumArgs <= std::distance(start, end)) {
|
if (m_num_args <= std::distance(start, end)) {
|
||||||
if (auto expected = maybe_nargs()) {
|
if (auto expected = maybe_nargs()) {
|
||||||
end = std::next(start, *expected);
|
end = std::next(start, *expected);
|
||||||
if (std::any_of(start, end, Argument::is_optional)) {
|
if (std::any_of(start, end, Argument::is_optional)) {
|
||||||
@ -487,14 +487,14 @@ public:
|
|||||||
|
|
||||||
struct ActionApply {
|
struct ActionApply {
|
||||||
void operator()(valued_action &f) {
|
void operator()(valued_action &f) {
|
||||||
std::transform(first, last, std::back_inserter(self.mValues), f);
|
std::transform(first, last, std::back_inserter(self.m_values), f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(void_action &f) {
|
void operator()(void_action &f) {
|
||||||
std::for_each(first, last, f);
|
std::for_each(first, last, f);
|
||||||
if (!self.mDefaultValue.has_value()) {
|
if (!self.m_default_value.has_value()) {
|
||||||
if (auto expected = self.maybe_nargs()) {
|
if (auto expected = self.maybe_nargs()) {
|
||||||
self.mValues.resize(*expected);
|
self.m_values.resize(*expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -502,14 +502,14 @@ public:
|
|||||||
Iterator first, last;
|
Iterator first, last;
|
||||||
Argument &self;
|
Argument &self;
|
||||||
};
|
};
|
||||||
std::visit(ActionApply{start, end, *this}, mAction);
|
std::visit(ActionApply{start, end, *this}, m_action);
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
if (mDefaultValue.has_value()) {
|
if (m_default_value.has_value()) {
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
throw std::runtime_error("Too few arguments for '" +
|
throw std::runtime_error("Too few arguments for '" +
|
||||||
std::string(mUsedName) + "'.");
|
std::string(m_used_name) + "'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -517,31 +517,31 @@ public:
|
|||||||
*/
|
*/
|
||||||
void validate() const {
|
void validate() const {
|
||||||
if (auto expected = maybe_nargs()) {
|
if (auto expected = maybe_nargs()) {
|
||||||
if (mIsOptional) {
|
if (m_is_optional) {
|
||||||
if (mIsUsed && mValues.size() != *expected && !mIsRepeatable &&
|
if (m_is_used && m_values.size() != *expected && !m_is_repeatable &&
|
||||||
!mDefaultValue.has_value()) {
|
!m_default_value.has_value()) {
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
stream << mUsedName << ": expected " << *expected << " argument(s). "
|
stream << m_used_name << ": expected " << *expected
|
||||||
<< mValues.size() << " provided.";
|
<< " argument(s). " << m_values.size() << " provided.";
|
||||||
throw std::runtime_error(stream.str());
|
throw std::runtime_error(stream.str());
|
||||||
}
|
}
|
||||||
// TODO: check if an implicit value was programmed for this argument
|
// TODO: check if an implicit value was programmed for this argument
|
||||||
if (!mIsUsed && !mDefaultValue.has_value() && mIsRequired) {
|
if (!m_is_used && !m_default_value.has_value() && m_is_required) {
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
stream << mNames[0] << ": required.";
|
stream << m_names[0] << ": required.";
|
||||||
throw std::runtime_error(stream.str());
|
throw std::runtime_error(stream.str());
|
||||||
}
|
}
|
||||||
if (mIsUsed && mIsRequired && mValues.empty()) {
|
if (m_is_used && m_is_required && m_values.empty()) {
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
stream << mUsedName << ": no value provided.";
|
stream << m_used_name << ": no value provided.";
|
||||||
throw std::runtime_error(stream.str());
|
throw std::runtime_error(stream.str());
|
||||||
}
|
}
|
||||||
} else if (mValues.size() != expected && !mDefaultValue.has_value()) {
|
} else if (m_values.size() != expected && !m_default_value.has_value()) {
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
if (!mUsedName.empty()) {
|
if (!m_used_name.empty()) {
|
||||||
stream << mUsedName << ": ";
|
stream << m_used_name << ": ";
|
||||||
}
|
}
|
||||||
stream << *expected << " argument(s) expected. " << mValues.size()
|
stream << *expected << " argument(s) expected. " << m_values.size()
|
||||||
<< " provided.";
|
<< " provided.";
|
||||||
throw std::runtime_error(stream.str());
|
throw std::runtime_error(stream.str());
|
||||||
}
|
}
|
||||||
@ -549,15 +549,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto maybe_nargs() const -> std::optional<std::size_t> {
|
auto maybe_nargs() const -> std::optional<std::size_t> {
|
||||||
if (mNumArgs < 0) {
|
if (m_num_args < 0) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
return static_cast<std::size_t>(mNumArgs);
|
return static_cast<std::size_t>(m_num_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t get_arguments_length() const {
|
std::size_t get_arguments_length() const {
|
||||||
return std::accumulate(std::begin(mNames), std::end(mNames), std::size_t(0),
|
return std::accumulate(std::begin(m_names), std::end(m_names),
|
||||||
[](const auto &sum, const auto &s) {
|
std::size_t(0), [](const auto &sum, const auto &s) {
|
||||||
return sum + s.size() +
|
return sum + s.size() +
|
||||||
1; // +1 for space between names
|
1; // +1 for space between names
|
||||||
});
|
});
|
||||||
@ -565,17 +565,17 @@ public:
|
|||||||
|
|
||||||
friend std::ostream &operator<<(std::ostream &stream,
|
friend std::ostream &operator<<(std::ostream &stream,
|
||||||
const Argument &argument) {
|
const Argument &argument) {
|
||||||
std::stringstream nameStream;
|
std::stringstream name_stream;
|
||||||
std::copy(std::begin(argument.mNames), std::end(argument.mNames),
|
std::copy(std::begin(argument.m_names), std::end(argument.m_names),
|
||||||
std::ostream_iterator<std::string>(nameStream, " "));
|
std::ostream_iterator<std::string>(name_stream, " "));
|
||||||
stream << nameStream.str() << "\t" << argument.mHelp;
|
stream << name_stream.str() << "\t" << argument.m_help;
|
||||||
if (argument.mDefaultValue.has_value()) {
|
if (argument.m_default_value.has_value()) {
|
||||||
if (!argument.mHelp.empty()) {
|
if (!argument.m_help.empty()) {
|
||||||
stream << " ";
|
stream << " ";
|
||||||
}
|
}
|
||||||
stream << "[default: " << argument.mDefaultValueRepr << "]";
|
stream << "[default: " << argument.m_default_value_repr << "]";
|
||||||
} else if (argument.mIsRequired) {
|
} else if (argument.m_is_required) {
|
||||||
if (!argument.mHelp.empty()) {
|
if (!argument.m_help.empty()) {
|
||||||
stream << " ";
|
stream << " ";
|
||||||
}
|
}
|
||||||
stream << "[required]";
|
stream << "[required]";
|
||||||
@ -584,22 +584,22 @@ public:
|
|||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool operator!=(const T &aRhs) const {
|
template <typename T> bool operator!=(const T &rhs) const {
|
||||||
return !(*this == aRhs);
|
return !(*this == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compare to an argument value of known type
|
* Compare to an argument value of known type
|
||||||
* @throws std::logic_error in case of incompatible types
|
* @throws std::logic_error in case of incompatible types
|
||||||
*/
|
*/
|
||||||
template <typename T> bool operator==(const T &aRhs) const {
|
template <typename T> bool operator==(const T &rhs) const {
|
||||||
if constexpr (!details::IsContainer<T>) {
|
if constexpr (!details::IsContainer<T>) {
|
||||||
return get<T>() == aRhs;
|
return get<T>() == rhs;
|
||||||
} else {
|
} else {
|
||||||
using ValueType = typename T::value_type;
|
using ValueType = typename T::value_type;
|
||||||
auto tLhs = get<T>();
|
auto lhs = get<T>();
|
||||||
return std::equal(std::begin(tLhs), std::end(tLhs), std::begin(aRhs),
|
return std::equal(std::begin(lhs), std::end(lhs), std::begin(rhs),
|
||||||
std::end(aRhs), [](const auto &lhs, const auto &rhs) {
|
std::end(rhs), [](const auto &lhs, const auto &rhs) {
|
||||||
return std::any_cast<const ValueType &>(lhs) == rhs;
|
return std::any_cast<const ValueType &>(lhs) == rhs;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -754,8 +754,8 @@ private:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_optional(std::string_view aName) {
|
static bool is_optional(std::string_view name) {
|
||||||
return !is_positional(aName);
|
return !is_positional(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -765,16 +765,16 @@ private:
|
|||||||
* '-' decimal-literal
|
* '-' decimal-literal
|
||||||
* !'-' anything
|
* !'-' anything
|
||||||
*/
|
*/
|
||||||
static bool is_positional(std::string_view aName) {
|
static bool is_positional(std::string_view name) {
|
||||||
switch (lookahead(aName)) {
|
switch (lookahead(name)) {
|
||||||
case eof:
|
case eof:
|
||||||
return true;
|
return true;
|
||||||
case '-': {
|
case '-': {
|
||||||
aName.remove_prefix(1);
|
name.remove_prefix(1);
|
||||||
if (aName.empty()) {
|
if (name.empty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return is_decimal_literal(aName);
|
return is_decimal_literal(name);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
@ -786,17 +786,17 @@ private:
|
|||||||
* @throws std::logic_error in case of incompatible types
|
* @throws std::logic_error in case of incompatible types
|
||||||
*/
|
*/
|
||||||
template <typename T> T get() const {
|
template <typename T> T get() const {
|
||||||
if (!mValues.empty()) {
|
if (!m_values.empty()) {
|
||||||
if constexpr (details::IsContainer<T>) {
|
if constexpr (details::IsContainer<T>) {
|
||||||
return any_cast_container<T>(mValues);
|
return any_cast_container<T>(m_values);
|
||||||
} else {
|
} else {
|
||||||
return std::any_cast<T>(mValues.front());
|
return std::any_cast<T>(m_values.front());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mDefaultValue.has_value()) {
|
if (m_default_value.has_value()) {
|
||||||
return std::any_cast<T>(mDefaultValue);
|
return std::any_cast<T>(m_default_value);
|
||||||
}
|
}
|
||||||
throw std::logic_error("No value provided for '" + mNames.back() + "'.");
|
throw std::logic_error("No value provided for '" + m_names.back() + "'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -805,55 +805,55 @@ private:
|
|||||||
* @returns The stored value if any, std::nullopt otherwise.
|
* @returns The stored value if any, std::nullopt otherwise.
|
||||||
*/
|
*/
|
||||||
template <typename T> auto present() const -> std::optional<T> {
|
template <typename T> auto present() const -> std::optional<T> {
|
||||||
if (mDefaultValue.has_value()) {
|
if (m_default_value.has_value()) {
|
||||||
throw std::logic_error("Argument with default value always presents");
|
throw std::logic_error("Argument with default value always presents");
|
||||||
}
|
}
|
||||||
if (mValues.empty()) {
|
if (m_values.empty()) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
if constexpr (details::IsContainer<T>) {
|
if constexpr (details::IsContainer<T>) {
|
||||||
return any_cast_container<T>(mValues);
|
return any_cast_container<T>(m_values);
|
||||||
}
|
}
|
||||||
return std::any_cast<T>(mValues.front());
|
return std::any_cast<T>(m_values.front());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static auto any_cast_container(const std::vector<std::any> &aOperand) -> T {
|
static auto any_cast_container(const std::vector<std::any> &operand) -> T {
|
||||||
using ValueType = typename T::value_type;
|
using ValueType = typename T::value_type;
|
||||||
|
|
||||||
T tResult;
|
T result;
|
||||||
std::transform(
|
std::transform(
|
||||||
std::begin(aOperand), std::end(aOperand), std::back_inserter(tResult),
|
std::begin(operand), std::end(operand), std::back_inserter(result),
|
||||||
[](const auto &value) { return std::any_cast<ValueType>(value); });
|
[](const auto &value) { return std::any_cast<ValueType>(value); });
|
||||||
return tResult;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> mNames;
|
std::vector<std::string> m_names;
|
||||||
std::string_view mUsedName;
|
std::string_view m_used_name;
|
||||||
std::string mHelp;
|
std::string m_help;
|
||||||
std::any mDefaultValue;
|
std::any m_default_value;
|
||||||
std::string mDefaultValueRepr;
|
std::string m_default_value_repr;
|
||||||
std::any mImplicitValue;
|
std::any m_implicit_value;
|
||||||
using valued_action = std::function<std::any(const std::string &)>;
|
using valued_action = std::function<std::any(const std::string &)>;
|
||||||
using void_action = std::function<void(const std::string &)>;
|
using void_action = std::function<void(const std::string &)>;
|
||||||
std::variant<valued_action, void_action> mAction{
|
std::variant<valued_action, void_action> m_action{
|
||||||
std::in_place_type<valued_action>,
|
std::in_place_type<valued_action>,
|
||||||
[](const std::string &aValue) { return aValue; }};
|
[](const std::string &value) { return value; }};
|
||||||
std::vector<std::any> mValues;
|
std::vector<std::any> m_values;
|
||||||
int mNumArgs = 1;
|
int m_num_args = 1;
|
||||||
bool mIsOptional : true;
|
bool m_is_optional : true;
|
||||||
bool mIsRequired : true;
|
bool m_is_required : true;
|
||||||
bool mIsRepeatable : true;
|
bool m_is_repeatable : true;
|
||||||
bool mIsUsed : true; // True if the optional argument is used by user
|
bool m_is_used : true; // True if the optional argument is used by user
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArgumentParser {
|
class ArgumentParser {
|
||||||
public:
|
public:
|
||||||
explicit ArgumentParser(std::string aProgramName = {},
|
explicit ArgumentParser(std::string program_name = {},
|
||||||
std::string aVersion = "1.0",
|
std::string version = "1.0",
|
||||||
default_arguments aArgs = default_arguments::all)
|
default_arguments add_args = default_arguments::all)
|
||||||
: mProgramName(std::move(aProgramName)), mVersion(std::move(aVersion)) {
|
: m_program_name(std::move(program_name)), m_version(std::move(version)) {
|
||||||
if ((aArgs & default_arguments::help) == default_arguments::help) {
|
if ((add_args & default_arguments::help) == default_arguments::help) {
|
||||||
add_argument("-h", "--help")
|
add_argument("-h", "--help")
|
||||||
.action([&](const auto &unused) {
|
.action([&](const auto &unused) {
|
||||||
std::cout << help().str();
|
std::cout << help().str();
|
||||||
@ -864,10 +864,10 @@ public:
|
|||||||
.implicit_value(true)
|
.implicit_value(true)
|
||||||
.nargs(0);
|
.nargs(0);
|
||||||
}
|
}
|
||||||
if ((aArgs & default_arguments::version) == default_arguments::version) {
|
if ((add_args & default_arguments::version) == default_arguments::version) {
|
||||||
add_argument("-v", "--version")
|
add_argument("-v", "--version")
|
||||||
.action([&](const auto &unused) {
|
.action([&](const auto &unused) {
|
||||||
std::cout << mVersion;
|
std::cout << m_version;
|
||||||
std::exit(0);
|
std::exit(0);
|
||||||
})
|
})
|
||||||
.default_value(false)
|
.default_value(false)
|
||||||
@ -881,19 +881,19 @@ public:
|
|||||||
ArgumentParser &operator=(ArgumentParser &&) = default;
|
ArgumentParser &operator=(ArgumentParser &&) = default;
|
||||||
|
|
||||||
ArgumentParser(const ArgumentParser &other)
|
ArgumentParser(const ArgumentParser &other)
|
||||||
: mProgramName(other.mProgramName),
|
: m_program_name(other.m_program_name),
|
||||||
mVersion(other.mVersion),
|
m_version(other.m_version),
|
||||||
mDescription(other.mDescription),
|
m_description(other.m_description),
|
||||||
mEpilog(other.mEpilog),
|
m_epilog(other.m_epilog),
|
||||||
mIsParsed(other.mIsParsed),
|
m_is_parsed(other.m_is_parsed),
|
||||||
mPositionalArguments(other.mPositionalArguments),
|
m_positional_arguments(other.m_positional_arguments),
|
||||||
mOptionalArguments(other.mOptionalArguments) {
|
m_optional_arguments(other.m_optional_arguments) {
|
||||||
for (auto it = std::begin(mPositionalArguments);
|
for (auto it = std::begin(m_positional_arguments);
|
||||||
it != std::end(mPositionalArguments); ++it) {
|
it != std::end(m_positional_arguments); ++it) {
|
||||||
index_argument(it);
|
index_argument(it);
|
||||||
}
|
}
|
||||||
for (auto it = std::begin(mOptionalArguments);
|
for (auto it = std::begin(m_optional_arguments);
|
||||||
it != std::end(mOptionalArguments); ++it) {
|
it != std::end(m_optional_arguments); ++it) {
|
||||||
index_argument(it);
|
index_argument(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -908,46 +908,46 @@ public:
|
|||||||
|
|
||||||
// Parameter packing
|
// Parameter packing
|
||||||
// Call add_argument with variadic number of string arguments
|
// Call add_argument with variadic number of string arguments
|
||||||
template <typename... Targs> Argument &add_argument(Targs... Fargs) {
|
template <typename... Targs> Argument &add_argument(Targs... f_args) {
|
||||||
using array_of_sv = std::array<std::string_view, sizeof...(Targs)>;
|
using array_of_sv = std::array<std::string_view, sizeof...(Targs)>;
|
||||||
auto tArgument = mOptionalArguments.emplace(cend(mOptionalArguments),
|
auto argument = m_optional_arguments.emplace(cend(m_optional_arguments),
|
||||||
array_of_sv{Fargs...});
|
array_of_sv{f_args...});
|
||||||
|
|
||||||
if (!tArgument->mIsOptional) {
|
if (!argument->m_is_optional) {
|
||||||
mPositionalArguments.splice(cend(mPositionalArguments),
|
m_positional_arguments.splice(cend(m_positional_arguments),
|
||||||
mOptionalArguments, tArgument);
|
m_optional_arguments, argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
index_argument(tArgument);
|
index_argument(argument);
|
||||||
return *tArgument;
|
return *argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parameter packed add_parents method
|
// Parameter packed add_parents method
|
||||||
// Accepts a variadic number of ArgumentParser objects
|
// Accepts a variadic number of ArgumentParser objects
|
||||||
template <typename... Targs>
|
template <typename... Targs>
|
||||||
ArgumentParser &add_parents(const Targs &...Fargs) {
|
ArgumentParser &add_parents(const Targs &...f_args) {
|
||||||
for (const ArgumentParser &tParentParser : {std::ref(Fargs)...}) {
|
for (const ArgumentParser &parent_parser : {std::ref(f_args)...}) {
|
||||||
for (const auto &tArgument : tParentParser.mPositionalArguments) {
|
for (const auto &argument : parent_parser.m_positional_arguments) {
|
||||||
auto it =
|
auto it = m_positional_arguments.insert(cend(m_positional_arguments),
|
||||||
mPositionalArguments.insert(cend(mPositionalArguments), tArgument);
|
argument);
|
||||||
index_argument(it);
|
index_argument(it);
|
||||||
}
|
}
|
||||||
for (const auto &tArgument : tParentParser.mOptionalArguments) {
|
for (const auto &argument : parent_parser.m_optional_arguments) {
|
||||||
auto it =
|
auto it =
|
||||||
mOptionalArguments.insert(cend(mOptionalArguments), tArgument);
|
m_optional_arguments.insert(cend(m_optional_arguments), argument);
|
||||||
index_argument(it);
|
index_argument(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgumentParser &add_description(std::string aDescription) {
|
ArgumentParser &add_description(std::string description) {
|
||||||
mDescription = std::move(aDescription);
|
m_description = std::move(description);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgumentParser &add_epilog(std::string aEpilog) {
|
ArgumentParser &add_epilog(std::string epilog) {
|
||||||
mEpilog = std::move(aEpilog);
|
m_epilog = std::move(epilog);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -956,8 +956,8 @@ public:
|
|||||||
* This variant is used mainly for testing
|
* This variant is used mainly for testing
|
||||||
* @throws std::runtime_error in case of any invalid argument
|
* @throws std::runtime_error in case of any invalid argument
|
||||||
*/
|
*/
|
||||||
void parse_args(const std::vector<std::string> &aArguments) {
|
void parse_args(const std::vector<std::string> &arguments) {
|
||||||
parse_args_internal(aArguments);
|
parse_args_internal(arguments);
|
||||||
parse_args_validate();
|
parse_args_validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -978,12 +978,11 @@ public:
|
|||||||
* @throws std::logic_error if the option has no value
|
* @throws std::logic_error if the option has no value
|
||||||
* @throws std::bad_any_cast if the option is not of type T
|
* @throws std::bad_any_cast if the option is not of type T
|
||||||
*/
|
*/
|
||||||
template <typename T = std::string>
|
template <typename T = std::string> T get(std::string_view arg_name) const {
|
||||||
T get(std::string_view aArgumentName) const {
|
if (!m_is_parsed) {
|
||||||
if (!mIsParsed) {
|
|
||||||
throw std::logic_error("Nothing parsed, no arguments are available.");
|
throw std::logic_error("Nothing parsed, no arguments are available.");
|
||||||
}
|
}
|
||||||
return (*this)[aArgumentName].get<T>();
|
return (*this)[arg_name].get<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Getter for options without default values.
|
/* Getter for options without default values.
|
||||||
@ -992,81 +991,81 @@ public:
|
|||||||
* @throws std::bad_any_cast if the option is not of type T
|
* @throws std::bad_any_cast if the option is not of type T
|
||||||
*/
|
*/
|
||||||
template <typename T = std::string>
|
template <typename T = std::string>
|
||||||
auto present(std::string_view aArgumentName) const -> std::optional<T> {
|
auto present(std::string_view arg_name) const -> std::optional<T> {
|
||||||
return (*this)[aArgumentName].present<T>();
|
return (*this)[arg_name].present<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Getter that returns true for user-supplied options. Returns false if not
|
/* Getter that returns true for user-supplied options. Returns false if not
|
||||||
* user-supplied, even with a default value.
|
* user-supplied, even with a default value.
|
||||||
*/
|
*/
|
||||||
auto is_used(std::string_view aArgumentName) const {
|
auto is_used(std::string_view arg_name) const {
|
||||||
return (*this)[aArgumentName].mIsUsed;
|
return (*this)[arg_name].m_is_used;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Indexing operator. Return a reference to an Argument object
|
/* Indexing operator. Return a reference to an Argument object
|
||||||
* Used in conjuction with Argument.operator== e.g., parser["foo"] == true
|
* Used in conjuction with Argument.operator== e.g., parser["foo"] == true
|
||||||
* @throws std::logic_error in case of an invalid argument name
|
* @throws std::logic_error in case of an invalid argument name
|
||||||
*/
|
*/
|
||||||
Argument &operator[](std::string_view aArgumentName) const {
|
Argument &operator[](std::string_view arg_name) const {
|
||||||
auto tIterator = mArgumentMap.find(aArgumentName);
|
auto it = m_argument_map.find(arg_name);
|
||||||
if (tIterator != mArgumentMap.end()) {
|
if (it != m_argument_map.end()) {
|
||||||
return *(tIterator->second);
|
return *(it->second);
|
||||||
}
|
}
|
||||||
if (aArgumentName.front() != '-') {
|
if (arg_name.front() != '-') {
|
||||||
std::string nameStr(aArgumentName);
|
std::string name(arg_name);
|
||||||
// "-" + aArgumentName
|
// "-" + arg_name
|
||||||
nameStr = "-" + nameStr;
|
name = "-" + name;
|
||||||
tIterator = mArgumentMap.find(nameStr);
|
it = m_argument_map.find(name);
|
||||||
if (tIterator != mArgumentMap.end()) {
|
if (it != m_argument_map.end()) {
|
||||||
return *(tIterator->second);
|
return *(it->second);
|
||||||
}
|
}
|
||||||
// "--" + aArgumentName
|
// "--" + arg_name
|
||||||
nameStr = "-" + nameStr;
|
name = "-" + name;
|
||||||
tIterator = mArgumentMap.find(nameStr);
|
it = m_argument_map.find(name);
|
||||||
if (tIterator != mArgumentMap.end()) {
|
if (it != m_argument_map.end()) {
|
||||||
return *(tIterator->second);
|
return *(it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw std::logic_error("No such argument: " + std::string(aArgumentName));
|
throw std::logic_error("No such argument: " + std::string(arg_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print help message
|
// Print help message
|
||||||
friend auto operator<<(std::ostream &stream, const ArgumentParser &parser)
|
friend auto operator<<(std::ostream &stream, const ArgumentParser &parser)
|
||||||
-> std::ostream & {
|
-> std::ostream & {
|
||||||
stream.setf(std::ios_base::left);
|
stream.setf(std::ios_base::left);
|
||||||
stream << "Usage: " << parser.mProgramName << " [options] ";
|
stream << "Usage: " << parser.m_program_name << " [options] ";
|
||||||
std::size_t tLongestArgumentLength = parser.get_length_of_longest_argument();
|
std::size_t longest_arg_length = parser.get_length_of_longest_argument();
|
||||||
|
|
||||||
for (const auto &argument : parser.mPositionalArguments) {
|
for (const auto &argument : parser.m_positional_arguments) {
|
||||||
stream << argument.mNames.front() << " ";
|
stream << argument.m_names.front() << " ";
|
||||||
}
|
}
|
||||||
stream << "\n\n";
|
stream << "\n\n";
|
||||||
|
|
||||||
if (!parser.mDescription.empty()) {
|
if (!parser.m_description.empty()) {
|
||||||
stream << parser.mDescription << "\n\n";
|
stream << parser.m_description << "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parser.mPositionalArguments.empty()) {
|
if (!parser.m_positional_arguments.empty()) {
|
||||||
stream << "Positional arguments:\n";
|
stream << "Positional arguments:\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &mPositionalArgument : parser.mPositionalArguments) {
|
for (const auto &argument : parser.m_positional_arguments) {
|
||||||
stream.width(tLongestArgumentLength);
|
stream.width(longest_arg_length);
|
||||||
stream << mPositionalArgument;
|
stream << argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parser.mOptionalArguments.empty()) {
|
if (!parser.m_optional_arguments.empty()) {
|
||||||
stream << (parser.mPositionalArguments.empty() ? "" : "\n")
|
stream << (parser.m_positional_arguments.empty() ? "" : "\n")
|
||||||
<< "Optional arguments:\n";
|
<< "Optional arguments:\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &mOptionalArgument : parser.mOptionalArguments) {
|
for (const auto &argument : parser.m_optional_arguments) {
|
||||||
stream.width(tLongestArgumentLength);
|
stream.width(longest_arg_length);
|
||||||
stream << mOptionalArgument;
|
stream << argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parser.mEpilog.empty()) {
|
if (!parser.m_epilog.empty()) {
|
||||||
stream << parser.mEpilog << "\n\n";
|
stream << parser.m_epilog << "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return stream;
|
return stream;
|
||||||
@ -1092,47 +1091,47 @@ private:
|
|||||||
/*
|
/*
|
||||||
* @throws std::runtime_error in case of any invalid argument
|
* @throws std::runtime_error in case of any invalid argument
|
||||||
*/
|
*/
|
||||||
void parse_args_internal(const std::vector<std::string> &aArguments) {
|
void parse_args_internal(const std::vector<std::string> &arguments) {
|
||||||
if (mProgramName.empty() && !aArguments.empty()) {
|
if (m_program_name.empty() && !arguments.empty()) {
|
||||||
mProgramName = aArguments.front();
|
m_program_name = arguments.front();
|
||||||
}
|
}
|
||||||
auto end = std::end(aArguments);
|
auto end = std::end(arguments);
|
||||||
auto positionalArgumentIt = std::begin(mPositionalArguments);
|
auto positional_argument_it = std::begin(m_positional_arguments);
|
||||||
for (auto it = std::next(std::begin(aArguments)); it != end;) {
|
for (auto it = std::next(std::begin(arguments)); it != end;) {
|
||||||
const auto &tCurrentArgument = *it;
|
const auto ¤t_argument = *it;
|
||||||
if (Argument::is_positional(tCurrentArgument)) {
|
if (Argument::is_positional(current_argument)) {
|
||||||
if (positionalArgumentIt == std::end(mPositionalArguments)) {
|
if (positional_argument_it == std::end(m_positional_arguments)) {
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"Maximum number of positional arguments exceeded");
|
"Maximum number of positional arguments exceeded");
|
||||||
}
|
}
|
||||||
auto tArgument = positionalArgumentIt++;
|
auto argument = positional_argument_it++;
|
||||||
it = tArgument->consume(it, end);
|
it = argument->consume(it, end);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto tIterator = mArgumentMap.find(tCurrentArgument);
|
auto arg_map_it = m_argument_map.find(current_argument);
|
||||||
if (tIterator != mArgumentMap.end()) {
|
if (arg_map_it != m_argument_map.end()) {
|
||||||
auto tArgument = tIterator->second;
|
auto argument = arg_map_it->second;
|
||||||
it = tArgument->consume(std::next(it), end, tIterator->first);
|
it = argument->consume(std::next(it), end, arg_map_it->first);
|
||||||
} else if (const auto &tCompoundArgument = tCurrentArgument;
|
} else if (const auto &compound_arg = current_argument;
|
||||||
tCompoundArgument.size() > 1 && tCompoundArgument[0] == '-' &&
|
compound_arg.size() > 1 && compound_arg[0] == '-' &&
|
||||||
tCompoundArgument[1] != '-') {
|
compound_arg[1] != '-') {
|
||||||
++it;
|
++it;
|
||||||
for (std::size_t j = 1; j < tCompoundArgument.size(); j++) {
|
for (std::size_t j = 1; j < compound_arg.size(); j++) {
|
||||||
auto tHypotheticalArgument = std::string{'-', tCompoundArgument[j]};
|
auto hypothetical_arg = std::string{'-', compound_arg[j]};
|
||||||
auto tIterator2 = mArgumentMap.find(tHypotheticalArgument);
|
auto arg_map_it2 = m_argument_map.find(hypothetical_arg);
|
||||||
if (tIterator2 != mArgumentMap.end()) {
|
if (arg_map_it2 != m_argument_map.end()) {
|
||||||
auto tArgument = tIterator2->second;
|
auto argument = arg_map_it2->second;
|
||||||
it = tArgument->consume(it, end, tIterator2->first);
|
it = argument->consume(it, end, arg_map_it2->first);
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("Unknown argument: " + tCurrentArgument);
|
throw std::runtime_error("Unknown argument: " + current_argument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("Unknown argument: " + tCurrentArgument);
|
throw std::runtime_error("Unknown argument: " + current_argument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mIsParsed = true;
|
m_is_parsed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1140,44 +1139,44 @@ private:
|
|||||||
*/
|
*/
|
||||||
void parse_args_validate() {
|
void parse_args_validate() {
|
||||||
// Check if all arguments are parsed
|
// Check if all arguments are parsed
|
||||||
std::for_each(std::begin(mArgumentMap), std::end(mArgumentMap),
|
std::for_each(std::begin(m_argument_map), std::end(m_argument_map),
|
||||||
[](const auto &argPair) {
|
[](const auto &pair) {
|
||||||
const auto &tArgument = argPair.second;
|
const auto &argument = pair.second;
|
||||||
tArgument->validate();
|
argument->validate();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used by print_help.
|
// Used by print_help.
|
||||||
std::size_t get_length_of_longest_argument() const {
|
std::size_t get_length_of_longest_argument() const {
|
||||||
if (mArgumentMap.empty()) {
|
if (m_argument_map.empty()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
std::vector<std::size_t> argumentLengths(mArgumentMap.size());
|
std::vector<std::size_t> argument_lengths(m_argument_map.size());
|
||||||
std::transform(std::begin(mArgumentMap), std::end(mArgumentMap),
|
std::transform(std::begin(m_argument_map), std::end(m_argument_map),
|
||||||
std::begin(argumentLengths), [](const auto &argPair) {
|
std::begin(argument_lengths), [](const auto &pair) {
|
||||||
const auto &tArgument = argPair.second;
|
const auto &argument = pair.second;
|
||||||
return tArgument->get_arguments_length();
|
return argument->get_arguments_length();
|
||||||
});
|
});
|
||||||
return *std::max_element(std::begin(argumentLengths),
|
return *std::max_element(std::begin(argument_lengths),
|
||||||
std::end(argumentLengths));
|
std::end(argument_lengths));
|
||||||
}
|
}
|
||||||
|
|
||||||
using list_iterator = std::list<Argument>::iterator;
|
using list_iterator = std::list<Argument>::iterator;
|
||||||
|
|
||||||
void index_argument(list_iterator argIt) {
|
void index_argument(list_iterator it) {
|
||||||
for (const auto &mName : std::as_const(argIt->mNames)) {
|
for (const auto &name : std::as_const(it->m_names)) {
|
||||||
mArgumentMap.insert_or_assign(mName, argIt);
|
m_argument_map.insert_or_assign(name, it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string mProgramName;
|
std::string m_program_name;
|
||||||
std::string mVersion;
|
std::string m_version;
|
||||||
std::string mDescription;
|
std::string m_description;
|
||||||
std::string mEpilog;
|
std::string m_epilog;
|
||||||
bool mIsParsed = false;
|
bool m_is_parsed = false;
|
||||||
std::list<Argument> mPositionalArguments;
|
std::list<Argument> m_positional_arguments;
|
||||||
std::list<Argument> mOptionalArguments;
|
std::list<Argument> m_optional_arguments;
|
||||||
std::map<std::string_view, list_iterator, std::less<>> mArgumentMap;
|
std::map<std::string_view, list_iterator, std::less<>> m_argument_map;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace argparse
|
} // namespace argparse
|
||||||
|
Loading…
Reference in New Issue
Block a user