SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
aligned_sequence_concept.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
11#pragma once
12
13#include <algorithm>
14#include <ranges>
15
20
21// ---------------------------------------------------------------------------------------------------------------------
22// unaligned_seq transformation trait
23// ---------------------------------------------------------------------------------------------------------------------
24
26{
27
29template <template <typename...> typename container_type, typename seq_alph_t, typename... rest_t>
31constexpr auto remove_gap_from_value_type(container_type<gapped<seq_alph_t>, rest_t...>)
32 -> container_type<seq_alph_t, rest_t...>;
33
35template <template <typename...> typename container_type,
36 template <typename...>
37 typename allocator_type,
38 typename seq_alph_t,
39 typename... rest_t>
40 requires container<container_type<gapped<seq_alph_t>, allocator_type<gapped<seq_alph_t>>, rest_t...>>
41constexpr auto
42 remove_gap_from_value_type(container_type<gapped<seq_alph_t>, allocator_type<gapped<seq_alph_t>>, rest_t...>)
43 -> container_type<seq_alph_t, allocator_type<seq_alph_t>, rest_t...>;
44
46template <typename t>
48{};
49
51template <typename t>
52 requires (!requires { typename std::remove_reference_t<t>::unaligned_sequence_type; })
53 && requires { remove_gap_from_value_type(std::declval<t>()); }
55{
57 using type = decltype(remove_gap_from_value_type(std::declval<t>()));
58};
59
60// customisation point for our gap decorators.
62template <typename t>
63 requires requires { typename std::remove_reference_t<t>::unaligned_sequence_type; }
64struct unaligned_seq<t>
65{
67};
68
70template <typename t>
72
73} // namespace seqan3::detail
74
75// ---------------------------------------------------------------------------------------------------------------------
76// aligned_sequence
77// ---------------------------------------------------------------------------------------------------------------------
78
79namespace seqan3
80{
81
103template <typename t>
104concept aligned_sequence = sequence<t> && std::equality_comparable_with<std::ranges::range_reference_t<t>, gap>;
106
213template <typename t>
215 aligned_sequence<t> && std::ranges::forward_range<t> && requires { typename detail::unaligned_seq_t<t>; }
216 && requires (t v, detail::unaligned_seq_t<t> unaligned) {
217 // global functions for generic usability
218 {
219 insert_gap(v, std::ranges::begin(v))
220 } -> std::same_as<std::ranges::iterator_t<t>>;
221 {
222 insert_gap(v, std::ranges::begin(v), 2)
223 } -> std::same_as<std::ranges::iterator_t<t>>;
224 {
225 erase_gap(v, std::ranges::begin(v))
226 } -> std::same_as<std::ranges::iterator_t<t>>;
227 {
228 erase_gap(v, std::ranges::begin(v), std::ranges::end(v))
229 } -> std::same_as<std::ranges::iterator_t<t>>;
230 {
231 assign_unaligned(v, unaligned)
232 } -> std::same_as<void>;
233 };
235
236// ---------------------------------------------------------------------------------------------------------------------
237// Aligned sequence interface for containers over the seqan3::gapped alphabet
238// ---------------------------------------------------------------------------------------------------------------------
239
260template <sequence_container aligned_seq_t>
261 requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
262inline typename aligned_seq_t::iterator insert_gap(aligned_seq_t & aligned_seq,
263 typename aligned_seq_t::const_iterator pos_it)
264{
265 return aligned_seq.insert(pos_it, std::iter_value_t<aligned_seq_t>{gap{}});
266}
267
284template <sequence_container aligned_seq_t>
285 requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
286inline typename aligned_seq_t::iterator insert_gap(aligned_seq_t & aligned_seq,
287 typename aligned_seq_t::const_iterator pos_it,
288 typename aligned_seq_t::size_type size)
289{
290 return aligned_seq.insert(pos_it, size, std::iter_value_t<aligned_seq_t>{gap{}});
291}
292
312template <sequence_container aligned_seq_t>
313 requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
314inline typename aligned_seq_t::iterator erase_gap(aligned_seq_t & aligned_seq,
315 typename aligned_seq_t::const_iterator pos_it)
316{
317 if (*pos_it != gap{}) // [[unlikely]]
318 throw gap_erase_failure("The position to be erased does not contain a gap.");
319
320 return aligned_seq.erase(pos_it);
321}
322
343template <sequence_container aligned_seq_t>
344 requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
345inline typename aligned_seq_t::iterator erase_gap(aligned_seq_t & aligned_seq,
346 typename aligned_seq_t::const_iterator first,
347 typename aligned_seq_t::const_iterator last)
348{
349 for (auto it = first; it != last; ++it)
350 if (*it != gap{}) // [[unlikely]]
351 throw gap_erase_failure("The range to be erased contains at least one non-gap character.");
352
353 return aligned_seq.erase(first, last);
354}
355
378template <sequence_container aligned_seq_t, std::ranges::forward_range unaligned_sequence_type>
379 requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
381 std::ranges::range_reference_t<unaligned_sequence_type>>
382inline void assign_unaligned(aligned_seq_t & aligned_seq, unaligned_sequence_type && unaligned_seq)
383{
384 using std::swap;
385 aligned_seq_t tmp;
386 tmp.resize(std::ranges::distance(unaligned_seq));
387#if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY
388# pragma GCC diagnostic push
389# pragma GCC diagnostic ignored "-Wstringop-overflow"
390#endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY
391 std::ranges::copy(unaligned_seq, std::ranges::begin(tmp));
392#if SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY
393# pragma GCC diagnostic pop
394#endif // SEQAN3_WORKAROUND_GCC_BOGUS_MEMCPY
395 swap(aligned_seq, tmp);
396}
398
419template <typename range_type>
420 requires requires (range_type v) {
421 v.insert_gap(std::ranges::iterator_t<range_type>{});
422 v.insert_gap(std::ranges::iterator_t<range_type>{}, typename range_type::size_type{});
423 }
424std::ranges::iterator_t<range_type> insert_gap(range_type & rng,
425 std::ranges::iterator_t<range_type> const pos_it,
426 typename range_type::size_type const size = 1)
427{
428 return rng.insert_gap(pos_it, size);
429}
430
447template <typename range_type>
448 requires requires (range_type v) { v.erase_gap(std::ranges::iterator_t<range_type>{}); }
449std::ranges::iterator_t<range_type> erase_gap(range_type & rng, std::ranges::iterator_t<range_type> const pos_it)
450{
451 return rng.erase_gap(pos_it);
452}
453
472template <typename range_type>
473 requires requires (range_type v) {
474 v.erase_gap(std::ranges::iterator_t<range_type>{}, std::ranges::iterator_t<range_type>{});
475 }
476std::ranges::iterator_t<range_type> erase_gap(range_type & rng,
477 std::ranges::iterator_t<range_type> const first,
478 std::ranges::iterator_t<range_type> const last)
479{
480 return rng.erase_gap(first, last);
481}
483} // namespace seqan3
484
485namespace seqan3::detail
486{
487
491template <typename... elems>
492inline constexpr bool all_model_aligned_seq = (aligned_sequence<elems> && ...);
493
497template <typename... elems>
498inline constexpr bool all_model_aligned_seq<type_list<elems...>> = all_model_aligned_seq<elems...>;
499} // namespace seqan3::detail
Includes customized exception types for the alignment module .
T begin(T... args)
A combined alphabet that can hold values of either of its alternatives..
Definition alphabet_variant.hpp:129
The alphabet of a gap character '-'.
Definition gap.hpp:36
T copy(T... args)
Provides seqan3::gapped.
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:286
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:382
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)
An implementation of seqan3::writable_aligned_sequence::erase_gap for ranges with the corresponding m...
Definition aligned_sequence_concept.hpp:476
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:314
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:449
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:345
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:424
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:262
The generic concept for an aligned sequence.
The (most general) container concept as defined by the standard library.
The generic concept for a (biological) sequence.
Resolves to std::is_assignable_v<t>.
The generic concept for an aligned sequence that is writable.
The internal SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
constexpr auto remove_gap_from_value_type(container_type< gapped< seq_alph_t >, rest_t... >) -> container_type< seq_alph_t, rest_t... >
Helper function to deduce the unaligned sequence type from an aligned sequence container.
typename unaligned_seq< t >::type unaligned_seq_t
Helper type that delegates to seqan3::detail::unaligned_seq::type.
Definition aligned_sequence_concept.hpp:71
constexpr bool all_model_aligned_seq
True, if each type models seqan3::aligned_sequence; false otherwise.
Definition aligned_sequence_concept.hpp:492
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
Additional non-standard concepts for ranges.
decltype(remove_gap_from_value_type(std::declval< t >())) type
The unaligned sequence type of t.
Definition aligned_sequence_concept.hpp:57
Default transformation trait that shall expose the unaligned sequence type of t when specialised.
Definition aligned_sequence_concept.hpp:48
Type that contains multiple types.
Definition type_list.hpp:26
T swap(T... args)
Adaptations of concepts from the standard library.
Hide me