-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enum support for the argument parser #1196
Conversation
In general we can do it this way. Some notes:
|
But doesn't this work through ADL automatically?
Agreed. The name is ugly anyway but I am bad in naming. Suggestions? This also refers to naming it to something non-enum-specific. |
The same rules apply as anywhere else, or how is this different from
They are name-value-pairs so I would name them something like that. I would probably make a name_value_table and implement it as a variable. |
The difference is that we do not supply a global |
8a3f4c8
to
b535497
Compare
Codecov Report
@@ Coverage Diff @@
## master #1196 +/- ##
==========================================
+ Coverage 97.52% 97.52% +<.01%
==========================================
Files 226 226
Lines 8760 8778 +18
==========================================
+ Hits 8543 8561 +18
Misses 217 217
Continue to review full report at Codecov.
|
dbca685
to
6201278
Compare
dbbed0b
to
ddc4d81
Compare
eda8ad3
to
1556454
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing, otherwise LGTM
1556454
to
b6349c7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The general structure and everything looks good, but some things should be changed I think:
- if you call it a map, you should make it a variable and not a function. See for example alphabet_size for how that works with CPOs
- "string conversion" is a very broad term, are you sure that's good? Maybe call it
named_values
? Name-value-pair and attribute-value-pair are popular names for this, I think... it also depends on the order of key/value... maybe alsovalue_to_name_map
. - enforce in the CPO that stuff actually has the right type
- use ordered_map so that you have an order in the arg parser
- make the name type a string_view instead of a string.
2ca02ec
to
67bbeb0
Compare
@h-2 Can you take a look? |
4c6fe75
to
7055baf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a a general design question: you seem to be added documentation to the man-page on which values are valid for the enum and you are using the value_list_validator for this. But then I don't see you actually using the value_list_validator as the validator!
And how does this relate to a (different) validator supplied by the user?
I would design it differently:
- don't automatically assume anything about affected types.
- provide an "enum_validator" that is a valid_values_validator with the extracted strings.
This adds less hacky-special-case code and allows people to e.g. select a subset of values that they want to accept.
7055baf
to
9521717
Compare
As discussed eprsonally I remove the automativ valid values but did not add a special enum_validator. The user can simply use |
81052e7
to
840e08c
Compare
d450b8a
to
969fa64
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is all just minor stuff, feel free to merge this once these things have been fixed!
* It acts as a wrapper and looks for two possible implementations (in this order): | ||
* | ||
* 1. A static member `enumeration_names` in `seqan3::custom::argument_parsing<your_type>` that is of type | ||
* `std::unordered_map<std::string_view, your_type>>`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should relax these constraints to just be an "associative range", but that can be done later.
test/snippet/argument_parser/custom_argument_parsing_enumeration.cpp
Outdated
Show resolved
Hide resolved
test/snippet/argument_parser/custom_argument_parsing_enumeration.cpp
Outdated
Show resolved
Hide resolved
// the static member function enumeration_names | ||
// you can now add an option that takes a value of type std::errc: | ||
parser.add_option(value, 'e', "errc", "Give me a std::errc value.", seqan3::option_spec::DEFAULT, | ||
seqan3::value_list_validator{(seqan3::enumeration_names<std::errc> | seqan3::views::get<1>)}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the mechanism of using seqan3::views::get
documented anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean? This is a snippet that appears in the documentation of "how to specialise this". Is that documentation enough?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just think that most users will be surprised that you can iterate over values/keys of an associative container using views::get<>
.
If this is not explained anywhere, I think it would be good to add a sentence as explanation. But this can also be done later if you add a card.
969fa64
to
3419310
Compare
3419310
to
2870037
Compare
{ | ||
return impl(priority_tag<1>{}, s_option_t{}); | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This stuff could be much simpler, but it doesn't have to block this PR. We can fix it later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these should work, too. If you do update this, please check. If not, it's not important.
Fell free to merge.
// Specialise a mapping from an identifying string to the respective value of your type bar. | ||
auto enumeration_names(bar) | ||
{ | ||
return std::unordered_map<std::string_view, bar>{{{"one", bar::one}, {"two", bar::two}, {"three", bar::three}}};; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return std::unordered_map<std::string_view, bar>{{{"one", bar::one}, {"two", bar::two}, {"three", bar::three}}};; | |
return std::unordered_map<std::string_view, bar>{{"one", bar::one}, {"two", bar::two}, {"three", bar::three}};; |
?
|
||
auto enumeration_names(foo) | ||
{ | ||
return std::unordered_map<std::string_view, foo>{{{"one", foo::one}, {"two", foo::two}, {"three", foo::three}}}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return std::unordered_map<std::string_view, foo>{{{"one", foo::one}, {"two", foo::two}, {"three", foo::three}}}; | |
return std::unordered_map<std::string_view, foo>{{"one", foo::one}, {"two", foo::two}, {"three", foo::three}}; |
{ | ||
static inline std::unordered_map<std::string_view, Other::bar> const enumeration_names | ||
{ | ||
{{"one", Other::bar::one}, {"two", Other::bar::two}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{{"one", Other::bar::one}, {"two", Other::bar::two}} | |
{"one", Other::bar::one}, {"two", Other::bar::two} |
test/unit/core/debug_stream_test.cpp
Outdated
|
||
auto enumeration_names(Foo) | ||
{ | ||
return std::unordered_map<std::string_view, Foo>{{{"one", Foo::one}, {"two", Foo::two}}}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return std::unordered_map<std::string_view, Foo>{{{"one", Foo::one}, {"two", Foo::two}}}; | |
return std::unordered_map<std::string_view, Foo>{{"one", Foo::one}, {"two", Foo::two}}; |
2870037
to
9bd13c3
Compare
Can you approve the PR then 😁 ? |
No description provided.