Skip to content
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] Update writable_alphabet concept #2337

Merged
merged 3 commits into from
Feb 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ If possible, provide tooling that performs the changes, e.g. a shell-script.

## API changes

#### Alphabet

* Removed seqan3::char_is_valid_for requirement from seqan3::writable_alphabet and seqan3::writable_constexpr_alphabet
([\#2337](https://github.com/seqan/seqan3/pull/2337)).

#### Argument Parser

* The enum names of `seqan3::option_spec` were changed to lower case
Expand Down
3 changes: 1 addition & 2 deletions doc/howto/write_an_alphabet/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ your type also model these concepts.
\endsolution

At this point the seqan3::alphabet concept should be modelled successfully and even seqan3::writable_alphabet
is fine because we implemented `assign_char` and `char_is_valid`.
is fine because we implemented `assign_char`.
\snippet dna2_alphabet.cpp writable_alphabet_concept

## Shortcut: alphabet base template
Expand Down Expand Up @@ -183,4 +183,3 @@ from '1', 't' and 'T' for value 1 as well as from '0', 'f' and 'F' for value 0.
\note
You should really make your alphabet types [no-throw-default-constructible](\ref std::is_nothrow_default_constructible)
if you can!

31 changes: 20 additions & 11 deletions include/seqan3/alphabet/composite/alphabet_variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,21 +567,30 @@ class alphabet_variant : public alphabet_base<alphabet_variant<alternative_types
for (size_t i = 0u; i < table_size; ++i)
{
char_type chr = static_cast<char_type>(i);
bool there_was_no_valid_representation{true};

meta::for_each(alternatives{}, [&] (auto && alt)
std::array<bool, sizeof...(alternative_types)> is_char_valid{char_is_valid_for<alternative_types>(chr)...};
std::array<rank_type, sizeof...(alternative_types)> ranks
{
using alt_type = std::remove_cvref_t<decltype(alt)>;

if (there_was_no_valid_representation && char_is_valid_for<alt_type>(chr))
rank_by_type_(assign_char_to(chr, alternative_types{}))...
};

// if no char_is_valid_for any alternative use the rank of the first alternative
#if defined(__cpp_lib_constexpr_algorithms) && __cpp_lib_constexpr_algorithms >= 201806L
// the following lines only works beginning from c++20
auto found_it = std::find(is_char_valid.begin(), is_char_valid.end(), true);
auto found_index = found_it == is_char_valid.end() ? 0 : found_it - is_char_valid.begin();
#else
size_t found_index = 0u;
for (size_t k = 0u; k < is_char_valid.size(); ++k)
{
if (is_char_valid[k])
{
there_was_no_valid_representation = false;
char_to_rank[i] = rank_by_type_(assign_char_to(chr, alt_type{}));
found_index = k;
break;
}
});

if (there_was_no_valid_representation)
char_to_rank[i] = rank_by_type_(assign_char_to(chr, meta::front<alternatives>{}));
}
#endif // defined(__cpp_lib_constexpr_algorithms) && __cpp_lib_constexpr_algorithms >= 201806L
char_to_rank[i] = ranks[found_index];
}

return char_to_rank;
Expand Down
7 changes: 1 addition & 6 deletions include/seqan3/alphabet/concept.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,6 @@ SEQAN3_CONCEPT alphabet = semialphabet<t> && requires (t v)
* 1. `t` shall model seqan3::alphabet
* 2. `t` shall model seqan3::writable_semialphabet
* 3. seqan3::assign_char_to needs to be defined for objects of type `t`
* 4. seqan3::char_is_valid_for needs to be defined for type `t` and an argument of the character representation
*
* See the documentation pages for the respective requirements.
*
Expand All @@ -895,8 +894,6 @@ template <typename t>
SEQAN3_CONCEPT writable_alphabet = alphabet<t> && writable_semialphabet<t> && requires (t v, alphabet_char_t<t> c)
{
{ seqan3::assign_char_to(c, v) };

{ seqan3::char_is_valid_for<t>(c) };
};
//!\endcond

Expand Down Expand Up @@ -1035,8 +1032,7 @@ SEQAN3_CONCEPT constexpr_alphabet = constexpr_semialphabet<t> && alphabet<t> &&
* \ingroup alphabet
*
* Refines seqan3::detail::constexpr_alphabet, seqan3::detail::writable_constexpr_semialphabet and
* seqan3::writable_alphabet and requires that the calls to seqan3::assign_char_to and seqan3::char_is_valid_for
* can happen in a `constexpr`-context.
* seqan3::writable_alphabet and requires that the call to seqan3::assign_char_to can happen in a `constexpr`-context.
*/
//!\cond
template <typename t>
Expand All @@ -1045,7 +1041,6 @@ SEQAN3_CONCEPT writable_constexpr_alphabet =
{
// currently only tests rvalue interfaces, because we have no constexpr values in this scope to get references to
requires SEQAN3_IS_CONSTEXPR(seqan3::assign_char_to(alphabet_char_t<t>{}, std::remove_reference_t<t>{}));
requires SEQAN3_IS_CONSTEXPR(seqan3::char_is_valid_for<t>(alphabet_char_t<t>{}));
};
//!\endcond

Expand Down