-
Notifications
You must be signed in to change notification settings - Fork 80
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
[MISC] various fixes related to alphabet CPOs #1225
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1225 +/- ##
=======================================
Coverage 96.83% 96.83%
=======================================
Files 218 218
Lines 8748 8748
=======================================
Hits 8471 8471
Misses 277 277
Continue to review full report at Codecov.
|
Thanks for the review, what's you opinion on the design question? |
I actually like the new design better than the namespace solution. I did not see this way of doing it on the other blog posts so far, and from the ones I saw I prefer yours. But it feels like this is an area that will change over the next few years when more people start adopting this design so I wonder if it is the best way to adapt it later. This will probably be something we will consider in seqan4 (let's hope something similar to the proposal for using virtual and override on functions makes it into c++23). |
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.
mostly minor stuff.
In that case, you need to specialise the seqan3::custom::alphabet class template and provide the required functionality | ||
as static members. | ||
|
||
\snippet test/unit/alphabet/custom_alphabet3_test.cpp third_party_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 thought we don't use snippets anymore?
return intgr = chr; | ||
} | ||
/*!\brief Converting uint to rank is a no-op (it will just return the value you pass in). | ||
* \param intgr The alphabet letter that you wish to convert to rank. |
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.
* \param intgr The alphabet letter that you wish to convert to rank. | |
* \param[in] intgr The alphabet letter that you wish to convert to rank. |
and it looks like all other places
include/seqan3/alphabet/concept.hpp
Outdated
* \details | ||
* | ||
* For examples of when and how you can make use of this type, please see \link about_customisation the page on | ||
* customisation \endlink and the \link howto_write_an_alphabet_custom section on third party types \endlink in |
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.
* customisation \endlink and the \link howto_write_an_alphabet_custom section on third party types \endlink in | |
* customisation \endlink and the \link howto_write_an_alphabet_custom section on third party types \endlink in |
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.
not resolved
include/seqan3/alphabet/concept.hpp
Outdated
SEQAN3_CPO_IMPL(2, to_rank(v) ) // ADL | ||
SEQAN3_CPO_IMPL(1, seqan3::custom::to_rank(v) ) // customisation namespace | ||
SEQAN3_CPO_IMPL(0, v.to_rank() ) // member | ||
SEQAN3_CPO_IMPL(2, seqan3::custom::alphabet<decltype(v)>::to_rank(v) ) // explicit customisation |
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.
SEQAN3_CPO_IMPL(2, seqan3::custom::alphabet<decltype(v)>::to_rank(v) ) // explicit customisation | |
SEQAN3_CPO_IMPL(2, seqan3::custom::alphabet<decltype(v)>::to_rank(v)) // explicit customisation |
include/seqan3/alphabet/concept.hpp
Outdated
SEQAN3_CPO_IMPL(2, (assign_rank_to(args..., v) )) // ADL | ||
SEQAN3_CPO_IMPL(1, (seqan3::custom::assign_rank_to(args..., v) )) // customisation namespace | ||
SEQAN3_CPO_IMPL(0, (v.assign_rank(args...) )) // member | ||
SEQAN3_CPO_IMPL(2, (seqan3::custom::alphabet<decltype(v)>::assign_rank_to(args..., v) )) // explicit customisation |
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.
please remove the spaces in the end.
{ | ||
|
||
//!\brief Poison-pill overload to prevent non-ADL forms of unqualified lookup. | ||
template <typename ...args_t> | ||
void is_pair_close(args_t ...) = delete; |
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.
ellipse version
{ | ||
|
||
//!\brief Poison-pill overload to prevent non-ADL forms of unqualified lookup. | ||
template <typename ...args_t> | ||
void is_unpaired(args_t ...) = delete; |
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.
ellipse
{ | ||
|
||
//!\brief Poison-pill overload to prevent non-ADL forms of unqualified lookup. | ||
template <typename ...args_t> | ||
void max_pseudoknot_depth(args_t ...) = delete; |
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.
ellipse
{ | ||
|
||
//!\brief Poison-pill overload to prevent non-ADL forms of unqualified lookup. | ||
template <typename ...args_t> | ||
void pseudoknot_id(args_t ...) = delete; |
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.
ellipse
SEQAN3_CPO_IMPL(2, pseudoknot_id(v) ) // ADL | ||
SEQAN3_CPO_IMPL(1, seqan3::custom::pseudoknot_id(v) ) // customisation namespace | ||
SEQAN3_CPO_IMPL(0, v.pseudoknot_id() ) // member | ||
SEQAN3_CPO_IMPL(2, seqan3::custom::alphabet<decltype(v)>::pseudoknot_id(v) ) // explicit customisation |
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.
spaces
abac33d
to
bc95acd
Compare
polite review ping |
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.
💅 only
include/seqan3/alphabet/concept.hpp
Outdated
* \details | ||
* | ||
* For examples of when and how you can make use of this type, please see \link about_customisation the page on | ||
* customisation \endlink and the \link howto_write_an_alphabet_custom section on third party types \endlink in |
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.
not resolved
bc95acd
to
1abf2c5
Compare
ci is broken |
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 open remark
SEQAN3_CPO_IMPL(2, to_rank(v) ) // ADL | ||
SEQAN3_CPO_IMPL(1, seqan3::custom::to_rank(v) ) // customisation namespace | ||
SEQAN3_CPO_IMPL(0, v.to_rank() ) // member | ||
SEQAN3_CPO_IMPL(2, seqan3::custom::alphabet<decltype(v)>::to_rank(v)) // explicit customisation |
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.
Just a remark. We want the user to prefer overload in the respective objects namespace if possible. But why do we ask now in this order? Would the compiler not stop when it knows it found a valid overload and now it always has to begin with the least likely scenario and therefor affect the compile time? Just a thought.
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 am pretty sure the compiler needs to instantiate all IMPLs to find out what the valid overload-set is so it doesn't make a difference for compile-time.
However, it might make sense to document more clearly that we want people to provide implementations in the reverse order if possible.
Major change:
namespace seqan3::custom
anymore, because using that only worked if additions to it were included before the definition of the CPO.template <typename t> struct seqan3::custom
instead. It is specialised over the type that you are creating customisations for. Customisations are added asstatic
member functions instead of free functions (the struct acts like "namespace template").Other changes:
Open design question:
We now have one type that can be specialised for all customisation points. This means if someone wants T to model alphabet, and they also want T to model ArgParserValuable (or however the thing is going to be called) then they need to provide the customisations for both concepts in the same specialisation "instance" of seqan3::custom.
We could fix this by having
seqan3::custom::alphabet<T>
for the alphabet customisation points and then other sub-types inseqan3::custom::
for other customisation points, but I think this is a little overkill. 90% of our users will never write their own alphabets, 90% of the remaining users will program their types with members or ADL. 1% might want to adapt a third party type, but targetting a third party type that is already overloaded by a fourth-party for a different customisation point seems very unlikely. Even then they could do it with tricks likerequires true
.BUT I wanted to say it upfront.