SeqAn3 3.1.0
The Modern C++ library for sequence analysis.
aligned_sequence_concept.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2021, Knut Reinert & MPI für molekulare Genetik
4// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6// -----------------------------------------------------------------------------------------------------
7
14#pragma once
15
16#include <seqan3/std/algorithm>
17#include <seqan3/std/ranges>
18
23
24// ---------------------------------------------------------------------------------------------------------------------
25// unaligned_seq transformation trait
26// ---------------------------------------------------------------------------------------------------------------------
27
28namespace seqan3::detail
29{
30
32template <template <typename ...> typename container_type, typename seq_alph_t, typename ...rest_t>
36constexpr auto remove_gap_from_value_type(container_type<gapped<seq_alph_t>, rest_t...>)
37 -> container_type<seq_alph_t, rest_t...>;
38
40template <template <typename ...> typename container_type,
41 template <typename ...> typename allocator_type,
42 typename seq_alph_t, typename ...rest_t>
44 requires container<container_type<gapped<seq_alph_t>, allocator_type<gapped<seq_alph_t>>, rest_t...>>
46constexpr auto remove_gap_from_value_type(container_type<gapped<seq_alph_t>, allocator_type<gapped<seq_alph_t>>, rest_t...>)
47 -> container_type<seq_alph_t, allocator_type<seq_alph_t>, rest_t...>;
48
50template <typename t>
51struct unaligned_seq
52{};
53
55template <typename t>
57 requires (!requires { typename std::remove_reference_t<t>::unaligned_sequence_type; }) &&
58 requires { remove_gap_from_value_type(std::declval<t>()); }
60struct unaligned_seq<t>
61{
63 using type = decltype(remove_gap_from_value_type(std::declval<t>()));
64};
65
66// customisation point for our gap decorators.
68template <typename t>
70 requires requires { typename std::remove_reference_t<t>::unaligned_sequence_type; }
72struct unaligned_seq<t>
73{
75};
76
78template <typename t>
79using unaligned_seq_t = typename unaligned_seq<t>::type;
80
81} // namespace seqan3::detail
82
83// ---------------------------------------------------------------------------------------------------------------------
84// aligned_sequence
85// ---------------------------------------------------------------------------------------------------------------------
86
87namespace seqan3
88{
89
111template <typename t>
112SEQAN3_CONCEPT aligned_sequence =
113 sequence<t> &&
114 std::equality_comparable_with<std::ranges::range_reference_t<t>, gap>;
116
223template <typename t>
224SEQAN3_CONCEPT writable_aligned_sequence =
226 std::ranges::forward_range<t> &&
227 requires { typename detail::unaligned_seq_t<t>; } &&
228 requires (t v, detail::unaligned_seq_t<t> unaligned)
229 {
230 // global functions for generic usability
231 SEQAN3_RETURN_TYPE_CONSTRAINT(insert_gap(v, std::ranges::begin(v)), std::same_as, std::ranges::iterator_t<t>);
232 SEQAN3_RETURN_TYPE_CONSTRAINT(insert_gap(v, std::ranges::begin(v), 2),
233 std::same_as, std::ranges::iterator_t<t>);
234 SEQAN3_RETURN_TYPE_CONSTRAINT(erase_gap(v, std::ranges::begin(v)), std::same_as, std::ranges::iterator_t<t>);
235 SEQAN3_RETURN_TYPE_CONSTRAINT(erase_gap(v, std::ranges::begin(v), std::ranges::end(v)),
236 std::same_as, std::ranges::iterator_t<t>);
237 SEQAN3_RETURN_TYPE_CONSTRAINT(assign_unaligned(v, unaligned), std::same_as, void);
238 };
240
241// ---------------------------------------------------------------------------------------------------------------------
242// Aligned sequence interface for containers over the seqan3::gapped alphabet
243// ---------------------------------------------------------------------------------------------------------------------
244
265template <sequence_container aligned_seq_t>
267 requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
269inline typename aligned_seq_t::iterator insert_gap(aligned_seq_t & aligned_seq,
270 typename aligned_seq_t::const_iterator pos_it)
271{
272 return aligned_seq.insert(pos_it, std::iter_value_t<aligned_seq_t>{gap{}});
273}
274
291template <sequence_container aligned_seq_t>
293 requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
295inline typename aligned_seq_t::iterator insert_gap(aligned_seq_t & aligned_seq,
296 typename aligned_seq_t::const_iterator pos_it,
297 typename aligned_seq_t::size_type size)
298{
299 return aligned_seq.insert(pos_it, size, std::iter_value_t<aligned_seq_t>{gap{}});
300}
301
321template <sequence_container aligned_seq_t>
323 requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
325inline typename aligned_seq_t::iterator erase_gap(aligned_seq_t & aligned_seq,
326 typename aligned_seq_t::const_iterator pos_it)
327{
328 if (*pos_it != gap{}) // [[unlikely]]
329 throw gap_erase_failure("The position to be erased does not contain a gap.");
330
331 return aligned_seq.erase(pos_it);
332}
333
354template <sequence_container aligned_seq_t>
356 requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
358inline typename aligned_seq_t::iterator erase_gap(aligned_seq_t & aligned_seq,
359 typename aligned_seq_t::const_iterator first,
360 typename aligned_seq_t::const_iterator last)
361{
362 for (auto it = first; it != last; ++it)
363 if (*it != gap{}) // [[unlikely]]
364 throw gap_erase_failure("The range to be erased contains at least one non-gap character.");
365
366 return aligned_seq.erase(first, last);
367}
368
391template <sequence_container aligned_seq_t, std::ranges::forward_range unaligned_sequence_type>
393 requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>> &&
395 std::ranges::range_reference_t<unaligned_sequence_type>>
397inline void assign_unaligned(aligned_seq_t & aligned_seq, unaligned_sequence_type && unaligned_seq)
398{
399 using std::swap;
400 aligned_seq_t tmp;
401 tmp.resize(std::ranges::distance(unaligned_seq));
402 std::ranges::copy(unaligned_seq, std::ranges::begin(tmp));
403 swap(aligned_seq, tmp);
404}
406
427template <typename range_type>
429 requires requires (range_type v)
430 {
431 v.insert_gap(std::ranges::iterator_t<range_type>{});
432 v.insert_gap(std::ranges::iterator_t<range_type>{}, typename range_type::size_type{});
433 }
435std::ranges::iterator_t<range_type> insert_gap(range_type & rng,
436 std::ranges::iterator_t<range_type> const pos_it,
437 typename range_type::size_type const size = 1)
438{
439 return rng.insert_gap(pos_it, size);
440}
441
458template <typename range_type>
460 requires requires (range_type v) { v.erase_gap(std::ranges::iterator_t<range_type>{}); }
462std::ranges::iterator_t<range_type> erase_gap(range_type & rng,
463 std::ranges::iterator_t<range_type> const pos_it)
464{
465 return rng.erase_gap(pos_it);
466}
467
486template <typename range_type>
488 requires requires (range_type v) { v.erase_gap(std::ranges::iterator_t<range_type>{}, std::ranges::iterator_t<range_type>{}); }
490std::ranges::iterator_t<range_type> erase_gap(range_type & rng,
491 std::ranges::iterator_t<range_type> const first,
492 std::ranges::iterator_t<range_type> const last)
493{
494 return rng.erase_gap(first, last);
495}
497} // namespace seqan3
498
499namespace seqan3::detail
500{
501
505template <typename ...elems>
506inline bool constexpr all_model_aligned_seq = (aligned_sequence<elems> && ...);
507
511template <typename ...elems>
512inline bool constexpr all_model_aligned_seq<type_list<elems...>> = all_model_aligned_seq<elems...>;
513} // namespace seqan3::detail
The <algorithm> header from C++20's standard library.
Includes customized exception types for the alignment module .
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:295
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:397
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:490
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:325
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:462
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:358
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:435
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:269
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:151
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 main SeqAn3 namespace.
Definition: cigar_operation_table.hpp:2
#define SEQAN3_RETURN_TYPE_CONSTRAINT(expression, concept_name,...)
Same as writing {expression} -> concept_name<type1[, ...]> in a concept definition.
Definition: platform.hpp:57
The <ranges> header from C++20's standard library.
Additional non-standard concepts for ranges.
T swap(T... args)
Adaptations of concepts from the standard library.