SeqAn3  3.0.2
The Modern C++ library for sequence analysis.
aligned_sequence_concept.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, 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 
21 #include <seqan3/range/concept.hpp>
23 
24 // ---------------------------------------------------------------------------------------------------------------------
25 // unaligned_seq transformation trait
26 // ---------------------------------------------------------------------------------------------------------------------
27 
28 namespace seqan3::detail
29 {
30 
32 template <template <typename ...> typename container_type, typename seq_alph_t, typename ...rest_t>
36 constexpr auto remove_gap_from_value_type(container_type<gapped<seq_alph_t>, rest_t...>)
37  -> container_type<seq_alph_t, rest_t...>;
38 
40 template <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...>>
46 constexpr 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 
50 template <typename t>
51 struct unaligned_seq
52 {};
53 
55 template <typename t>
57  requires (!requires { typename std::remove_reference_t<t>::unaligned_seq_type; }) &&
58  requires { remove_gap_from_value_type(std::declval<t>()); }
60 struct 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.
68 template <typename t>
70  requires requires { typename std::remove_reference_t<t>::unaligned_seq_type; }
72 struct unaligned_seq<t>
73 {
75 };
76 
78 template <typename t>
79 using unaligned_seq_t = typename unaligned_seq<t>::type;
80 
81 } // namespace seqan3::detail
82 
83 // ---------------------------------------------------------------------------------------------------------------------
84 // aligned_sequence
85 // ---------------------------------------------------------------------------------------------------------------------
86 
87 namespace seqan3
88 {
89 
109 template <typename t>
112 SEQAN3_CONCEPT aligned_sequence =
113  sequence<t> &&
114  std::equality_comparable_with<std::ranges::range_reference_t<t>, gap>;
116 
222 template <typename t>
224 SEQAN3_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 
265 template <sequence_container aligned_seq_t>
267  requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
269 inline 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 
291 template <sequence_container aligned_seq_t>
293  requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
295 inline 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 
321 template <sequence_container aligned_seq_t>
323  requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
325 inline 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 
354 template <sequence_container aligned_seq_t>
356  requires detail::is_gapped_alphabet<std::iter_value_t<aligned_seq_t>>
358 inline 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 
391 template <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>>
397 inline 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 
427 template <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  }
435 std::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 
458 template <typename range_type>
460  requires requires (range_type v) { v.erase_gap(std::ranges::iterator_t<range_type>{}); }
462 std::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 
486 template <typename range_type>
488  requires requires (range_type v) { v.erase_gap(std::ranges::iterator_t<range_type>{}, std::ranges::iterator_t<range_type>{}); }
490 std::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 
499 namespace seqan3::detail
500 {
501 
505 template <typename ...elems>
506 inline bool constexpr all_model_aligned_seq = (aligned_sequence<elems> && ...);
507 
511 template <typename ...elems>
512 inline bool constexpr all_model_aligned_seq<type_list<elems...>> = all_model_aligned_seq<elems...>;
513 
517 template <typename ...elems>
518 inline bool constexpr all_model_writable_aligned_seq = (writable_aligned_sequence<elems> && ...);
519 
523 template <typename ...elems>
524 inline bool constexpr all_model_writable_aligned_seq<type_list<elems...>> = all_model_writable_aligned_seq<elems...>;
525 } // namespace seqan3::detail
writable_aligned_sequence::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:462
writable_aligned_sequence::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:435
seqan3::type_list
meta::list< types... > type_list
Type that contains multiple types, an alias for meta::list.
Definition: type_list.hpp:31
aligned_sequence
The generic concept for an aligned sequence.
concept.hpp
Adaptations of concepts from the standard library.
exception.hpp
Includes customized exception types for the alignment module .
algorithm
Adaptations of algorithms from the Ranges TS.
concept.hpp
Additional non-standard concepts for ranges.
seqan3::alphabet_variant
A combined alphabet that can hold values of either of its alternatives.
Definition: alphabet_variant.hpp:133
writable_aligned_sequence::erase_gap
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
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:358
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:295
gapped.hpp
Provides seqan3::gapped.
seqan3
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
SEQAN3_RETURN_TYPE_CONSTRAINT
#define SEQAN3_RETURN_TYPE_CONSTRAINT(expression, concept_name,...)
Same as writing {expression} -> concept_name<type1[, ...]> in a concept definition.
Definition: platform.hpp:57
std::iter_value_t
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:325
seqan3::pack_traits::size
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:116
std::swap
T swap(T... args)
ranges
Adaptations of concepts from the Ranges TS.
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:397
std::remove_reference_t
container
The (most general) container concept as defined by the standard library.
writable_aligned_sequence
The generic concept for an aligned sequence that is writable.
weakly_assignable_from
Resolves to std::is_assignable_v<t>.
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:269
sequence
The generic concept for a sequence.