Skip to content

Commit

Permalink
Support for number of short hand flag: eg. "-1"
Browse files Browse the repository at this point in the history
  • Loading branch information
gen740 committed Dec 13, 2023
1 parent 26d9093 commit b39ddef
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 24 deletions.
17 changes: 17 additions & 0 deletions Argo/ArgoMetaLookup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,23 @@ consteval auto SearchIndexFromShortName() {
return value;
}

/*!
* Index Search meta function
*/
template <class Tuple>
ARGO_ALWAYS_INLINE constexpr auto SearchIndexFromShortName(char c) {
int value = -1;
if (![&value, &c]<class... T>(type_sequence<T...>) ARGO_ALWAYS_INLINE {
return ((value++,
(T::name.shortName >= '0' and T::name.shortName <= '9') and
(c == T::name.shortName)) ||
...);
}(make_type_sequence_t<Tuple>())) {
return -1;
}
return value;
}

}; // namespace Argo

// generator end here
6 changes: 3 additions & 3 deletions Argo/ArgoParserImpl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::parse(int argc,

[[maybe_unused]] string_view key{};
vector<char> short_keys{};
short_keys.reserve(10);
short_keys.reserve(8);
vector<string_view> values{};
values.reserve(10);
values.reserve(8);

assert(this->info_); // this->info_ cannot be nullptr
if (!this->info_->program_name) {
Expand Down Expand Up @@ -125,7 +125,7 @@ constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::parse(int argc,
arg = argv[i];
is_flag = arg.starts_with('-');
if (arg.size() > 1 and arg.at(1) >= '0' and arg.at(1) <= '9') {
is_flag = false;
is_flag = SearchIndexFromShortName<Args>(arg.at(1)) != -1;
}
} else {
is_flag = true;
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ import std;
// suppose ./main --arg1 42 --arg3 "Hello,World"
auto main(int argc, char* argv[]) -> int {

auto parser = Argo::Parser() //
.addArg<"arg1", int>()
.addArg<"arg2", float>(Argo::explicitDefault(12.34))
.addArg<"arg3", std::string>();
auto parser = Argo::Parser() //
.addArg<"arg1", int>()
.addArg<"arg2", float>(Argo::explicitDefault(12.34))
.addArg<"arg3", std::string>();

parser.parse(argc, argv);

Expand Down
57 changes: 40 additions & 17 deletions include/Argo/Argo.hh
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,23 @@ consteval auto SearchIndexFromShortName() {
return value;
}

/*!
* Index Search meta function
*/
template <class Tuple>
ARGO_ALWAYS_INLINE constexpr auto SearchIndexFromShortName(char c) {
int value = -1;
if (![&value, &c]<class... T>(type_sequence<T...>) ARGO_ALWAYS_INLINE {
return ((value++,
(T::name.shortName >= '0' and T::name.shortName <= '9') and
(c == T::name.shortName)) ||
...);
}(make_type_sequence_t<Tuple>())) {
return -1;
}
return value;
}

}; // namespace Argo


Expand Down Expand Up @@ -1130,7 +1147,7 @@ ARGO_ALWAYS_INLINE constexpr auto Assigner(string_view key,
if (key.empty()) {
if constexpr (!is_same_v<PArgs, tuple<>>) {
if (!PArgAssigner<PArgs>(values)) {
throw InvalidArgument(format("Duplicated positional argument"));
throw InvalidArgument("Duplicated positional argument");
}
return;
} else {
Expand Down Expand Up @@ -1546,7 +1563,7 @@ namespace Argo {

using namespace std;

inline auto splitStringView(string_view str, char delimeter)
ARGO_ALWAYS_INLINE auto splitStringView(string_view str, char delimeter)
-> vector<string_view> {
vector<string_view> ret;
while (str.contains(delimeter)) {
Expand All @@ -1567,7 +1584,8 @@ constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::resetArgs() -> void {
template <ParserID ID, class Args, class PArgs, class HArg, class SubParsers>
requires(is_tuple_v<Args> && is_tuple_v<SubParsers>)
constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::setArg(
string_view key, span<string_view> val) const -> void {
[[maybe_unused]] string_view key,
[[maybe_unused]] span<string_view> val) const -> void {
if constexpr (!is_same_v<HArg, void>) {
if (key == HArg::name) {
std::cout << formatHelp() << '\n';
Expand All @@ -1580,7 +1598,8 @@ constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::setArg(
template <ParserID ID, class Args, class PArgs, class HArg, class SubParsers>
requires(is_tuple_v<Args> && is_tuple_v<SubParsers>)
constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::setArg(
span<char> key, span<string_view> val) const -> void {
[[maybe_unused]] span<char> key,
[[maybe_unused]] span<string_view> val) const -> void {
if constexpr (!is_same_v<HArg, void>) {
for (const auto& i : key) {
if constexpr (HArg::name.shortName != '\0') {
Expand All @@ -1596,8 +1615,9 @@ constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::setArg(

template <ParserID ID, class Args, class PArgs, class HArg, class SubParsers>
requires(is_tuple_v<Args> && is_tuple_v<SubParsers>)
inline constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::parse(
int argc, char* argv[]) -> void {
constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::parse(int argc,
char* argv[])
-> void {
if (this->parsed_) [[unlikely]] {
throw ParseError("Cannot parse twice");
}
Expand All @@ -1612,11 +1632,11 @@ inline constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::parse(
throw ParseError(format("keys {} already assigned", assigned_keys));
}

string_view key{};
[[maybe_unused]] string_view key{};
vector<char> short_keys{};
short_keys.reserve(10);
short_keys.reserve(8);
vector<string_view> values{};
values.reserve(10);
values.reserve(8);

assert(this->info_); // this->info_ cannot be nullptr
if (!this->info_->program_name) {
Expand All @@ -1637,17 +1657,20 @@ inline constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::parse(
}
}
}
bool flag = false;
string_view arg;
[[maybe_unused]] bool is_flag = false;
[[maybe_unused]] string_view arg;

for (int i = 1; i < cmd_end_pos + 1; i++) {
if (i != cmd_end_pos) {
arg = argv[i];
flag = arg.starts_with('-');
is_flag = arg.starts_with('-');
if (arg.size() > 1 and arg.at(1) >= '0' and arg.at(1) <= '9') {
is_flag = SearchIndexFromShortName<Args>(arg.at(1)) != -1;
}
} else {
flag = true;
is_flag = true;
}
if (i != 1 and flag) {
if (i != 1 and is_flag) {
if (!key.empty()) {
this->setArg(key, values);
key = "";
Expand All @@ -1665,16 +1688,16 @@ inline constexpr auto Parser<ID, Args, PArgs, HArg, SubParsers>::parse(
}
}
}
if (i == cmd_end_pos) {
if (i == cmd_end_pos) [[unlikely]] {
break;
}
if (flag) {
if (is_flag) {
if (arg.size() > 1 and arg.at(1) == '-') {
if (arg.contains('=')) [[unlikely]] {
auto equal_pos = arg.find('=');
key = arg.substr(2, equal_pos - 2);
values.push_back(arg.substr(equal_pos + 1));
flag = true;
is_flag = true;
} else {
key = arg.substr(2);
}
Expand Down

0 comments on commit b39ddef

Please sign in to comment.