Loading...
Searching...
No Matches
aligned_sequence_concept.hpp
Go to the documentation of this file.
// SPDX-FileCopyrightText: 2006-2025 Knut Reinert & Freie Universität Berlin
// SPDX-FileCopyrightText: 2016-2025 Knut Reinert & MPI für molekulare Genetik
// SPDX-License-Identifier: BSD-3-Clause
#pragma once
#include <algorithm>
#include <ranges>
#include <seqan3/alignment/exception.hpp>
#include <seqan3/alphabet/gap/gapped.hpp>
#include <seqan3/alphabet/range/sequence.hpp>
#include <seqan3/utility/container/concept.hpp>
// ---------------------------------------------------------------------------------------------------------------------
// unaligned_seq transformation trait
// ---------------------------------------------------------------------------------------------------------------------
namespace seqan3::detail
{
template <template <typename...> typename container_type, typename seq_alph_t, typename... rest_t>
requires container<container_type<gapped<seq_alph_t>, rest_t...>>
constexpr auto
remove_gap_from_value_type(container_type<gapped<seq_alph_t>, rest_t...>) -> container_type<seq_alph_t, rest_t...>;
template <template <typename...> typename container_type,
template <typename...>
typename allocator_type,
typename seq_alph_t,
typename... rest_t>
requires container<container_type<gapped<seq_alph_t>, allocator_type<gapped<seq_alph_t>>, rest_t...>>
constexpr auto
remove_gap_from_value_type(container_type<gapped<seq_alph_t>, allocator_type<gapped<seq_alph_t>>, rest_t...>)
-> container_type<seq_alph_t, allocator_type<seq_alph_t>, rest_t...>;
template <typename t>
struct unaligned_seq
{};
template <typename t>
requires (!requires { typename std::remove_reference_t<t>::unaligned_sequence_type; })
&& requires { remove_gap_from_value_type(std::declval<t>()); }
struct unaligned_seq<t>
{
using type = decltype(remove_gap_from_value_type(std::declval<t>()));
};
// customisation point for our gap decorators.
template <typename t>
requires requires { typename std::remove_reference_t<t>::unaligned_sequence_type; }
struct unaligned_seq<t>
{
using type = typename std::remove_reference_t<t>::unaligned_sequence_type;
};
template <typename t>
using unaligned_seq_t = typename unaligned_seq<t>::type;
} // namespace seqan3::detail
// ---------------------------------------------------------------------------------------------------------------------
// aligned_sequence
// ---------------------------------------------------------------------------------------------------------------------
namespace seqan3
{
template <typename t>
concept aligned_sequence = sequence<t> && std::equality_comparable_with<std::ranges::range_reference_t<t>, gap>;
template <typename t>
concept writable_aligned_sequence = aligned_sequence<t> && std::ranges::forward_range<t> && requires {
typename detail::unaligned_seq_t<t>;
} && requires (t v, detail::unaligned_seq_t<t> unaligned) {
// global functions for generic usability
{ insert_gap(v, std::ranges::begin(v)) } -> std::same_as<std::ranges::iterator_t<t>>;
{ insert_gap(v, std::ranges::begin(v), 2) } -> std::same_as<std::ranges::iterator_t<t>>;
{ erase_gap(v, std::ranges::begin(v)) } -> std::same_as<std::ranges::iterator_t<t>>;
{ erase_gap(v, std::ranges::begin(v), std::ranges::end(v)) } -> std::same_as<std::ranges::iterator_t<t>>;
{ assign_unaligned(v, unaligned) } -> std::same_as<void>;
};
// ---------------------------------------------------------------------------------------------------------------------
// Aligned sequence interface for containers over the seqan3::gapped alphabet
// ---------------------------------------------------------------------------------------------------------------------
template <sequence_container aligned_seq_t>
requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
inline typename aligned_seq_t::iterator insert_gap(aligned_seq_t & aligned_seq,
typename aligned_seq_t::const_iterator pos_it)
{
return aligned_seq.insert(pos_it, std::iter_value_t<aligned_seq_t>{gap{}});
}
template <sequence_container aligned_seq_t>
requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
inline typename aligned_seq_t::iterator insert_gap(aligned_seq_t & aligned_seq,
typename aligned_seq_t::const_iterator pos_it,
typename aligned_seq_t::size_type size)
{
return aligned_seq.insert(pos_it, size, std::iter_value_t<aligned_seq_t>{gap{}});
}
template <sequence_container aligned_seq_t>
requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
inline typename aligned_seq_t::iterator erase_gap(aligned_seq_t & aligned_seq,
typename aligned_seq_t::const_iterator pos_it)
{
if (*pos_it != gap{}) // [[unlikely]]
throw gap_erase_failure("The position to be erased does not contain a gap.");
return aligned_seq.erase(pos_it);
}
template <sequence_container aligned_seq_t>
requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
inline typename aligned_seq_t::iterator erase_gap(aligned_seq_t & aligned_seq,
typename aligned_seq_t::const_iterator first,
typename aligned_seq_t::const_iterator last)
{
for (auto it = first; it != last; ++it)
if (*it != gap{}) // [[unlikely]]
throw gap_erase_failure("The range to be erased contains at least one non-gap character.");
return aligned_seq.erase(first, last);
}
template <sequence_container aligned_seq_t, std::ranges::forward_range unaligned_sequence_type>
requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
&& weakly_assignable_from<std::ranges::range_reference_t<aligned_seq_t>,
std::ranges::range_reference_t<unaligned_sequence_type>>
inline void assign_unaligned(aligned_seq_t & aligned_seq, unaligned_sequence_type && unaligned_seq)
{
using std::swap;
aligned_seq_t tmp;
tmp.resize(std::ranges::distance(unaligned_seq));
SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(-Wstringop-overflow)
std::ranges::copy(unaligned_seq, std::ranges::begin(tmp));
SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_STOP
swap(aligned_seq, tmp);
}
template <typename range_type>
requires requires (range_type v) {
v.insert_gap(std::ranges::iterator_t<range_type>{});
v.insert_gap(std::ranges::iterator_t<range_type>{}, typename range_type::size_type{});
}
std::ranges::iterator_t<range_type> insert_gap(range_type & rng,
std::ranges::iterator_t<range_type> const pos_it,
typename range_type::size_type const size = 1)
{
return rng.insert_gap(pos_it, size);
}
template <typename range_type>
requires requires (range_type v) { v.erase_gap(std::ranges::iterator_t<range_type>{}); }
std::ranges::iterator_t<range_type> erase_gap(range_type & rng, std::ranges::iterator_t<range_type> const pos_it)
{
return rng.erase_gap(pos_it);
}
template <typename range_type>
requires requires (range_type v) {
v.erase_gap(std::ranges::iterator_t<range_type>{}, std::ranges::iterator_t<range_type>{});
}
std::ranges::iterator_t<range_type> erase_gap(range_type & rng,
std::ranges::iterator_t<range_type> const first,
std::ranges::iterator_t<range_type> const last)
{
return rng.erase_gap(first, last);
}
} // namespace seqan3
namespace seqan3::detail
{
template <typename... elems>
inline constexpr bool all_model_aligned_seq = (aligned_sequence<elems> && ...);
template <typename... elems>
inline constexpr bool all_model_aligned_seq<type_list<elems...>> = all_model_aligned_seq<elems...>;
} // namespace seqan3::detail
algorithm
exception.hpp
Includes customized exception types for the alignment module .
std::declval
T declval(T... args)
gapped.hpp
Provides seqan3::gapped.
writable_aligned_sequence::insert_gap
aligned_seq_t::iterator insert_gap(aligned_seq_t &aligned_seq, typename aligned_seq_t::const_iterator pos_it, typename aligned_seq_t::size_type size)
An implementation of seqan3::writable_aligned_sequence::insert_gap for sequence containers.
Definition aligned_sequence_concept.hpp:276
seqan3::erase_gap
std::ranges::iterator_t< range_type > erase_gap(range_type &rng, std::ranges::iterator_t< range_type > const pos_it)
An implementation of seqan3::writable_aligned_sequence::erase_gap for ranges with the corresponding m...
Definition aligned_sequence_concept.hpp:434
writable_aligned_sequence::assign_unaligned
void assign_unaligned(aligned_seq_t &aligned_seq, unaligned_sequence_type &&unaligned_seq)
An implementation of seqan3::writable_aligned_sequence::assign_unaligned_sequence for sequence contai...
Definition aligned_sequence_concept.hpp:372
writable_aligned_sequence::erase_gap
aligned_seq_t::iterator erase_gap(aligned_seq_t &aligned_seq, typename aligned_seq_t::const_iterator pos_it)
An implementation of seqan3::writable_aligned_sequence::erase_gap for sequence containers.
Definition aligned_sequence_concept.hpp:304
seqan3::insert_gap
std::ranges::iterator_t< range_type > insert_gap(range_type &rng, std::ranges::iterator_t< range_type > const pos_it, typename range_type::size_type const size=1)
An implementation of seqan3::writable_aligned_sequence::insert_gap for ranges with the corresponding ...
Definition aligned_sequence_concept.hpp:409
writable_aligned_sequence::erase_gap
aligned_seq_t::iterator erase_gap(aligned_seq_t &aligned_seq, typename aligned_seq_t::const_iterator first, typename aligned_seq_t::const_iterator last)
An implementation of seqan3::writable_aligned_sequence::erase_gap for sequence containers.
Definition aligned_sequence_concept.hpp:335
writable_aligned_sequence::insert_gap
aligned_seq_t::iterator insert_gap(aligned_seq_t &aligned_seq, typename aligned_seq_t::const_iterator pos_it)
An implementation of seqan3::writable_aligned_sequence::insert_gap for sequence containers.
Definition aligned_sequence_concept.hpp:252
seqan3::gapped
alphabet_variant< alphabet_t, gap > gapped
Extends a given alphabet with a gap character.
Definition gapped.hpp:38
aligned_sequence
The generic concept for an aligned sequence.
container
The (most general) container concept as defined by the standard library.
sequence
The generic concept for a (biological) sequence.
weakly_assignable_from
Resolves to std::is_assignable_v<t>.
writable_aligned_sequence
The generic concept for an aligned sequence that is writable.
seqan3
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START
#define SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_START(...)
Denotes the start of a block where diagnostics are ignored.
Definition platform.hpp:268
SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_STOP
#define SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY_STOP
Denotes the end of a block where diagnostics are ignored.
Definition platform.hpp:277
std::remove_reference_t
sequence.hpp
Additional non-standard concepts for ranges.
std::swap
T swap(T... args)
concept.hpp
Adaptations of concepts from the standard library.
Hide me