SeqAn3
align_config_sequence_ends.hpp
Go to the documentation of this file.
1 // ============================================================================
2 // SeqAn - The Library for Sequence Analysis
3 // ============================================================================
4 //
5 // Copyright (c) 2006-2018, Knut Reinert & Freie Universitaet Berlin
6 // Copyright (c) 2016-2018, Knut Reinert & MPI Molekulare Genetik
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // * Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // * Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in the
16 // documentation and/or other materials provided with the distribution.
17 // * Neither the name of Knut Reinert or the FU Berlin nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
25 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 // DAMAGE.
32 //
33 // ============================================================================
34 
40 #pragma once
41 
42 #include <iostream>
43 
48 
49 namespace seqan3
50 {
51 
57 enum struct free_ends_at : uint8_t
58 {
60  none = 0b0000,
62  seq1_front = 0b0001,
64  seq1_back = 0b0010,
66  seq2_front = 0b0100,
68  seq2_back = 0b1000,
70  seq1 = seq1_front | seq1_back,
72  seq2 = seq2_front | seq2_back,
74  all = seq1 | seq2
75 };
76 
78 template <>
79 constexpr bool add_enum_bitwise_operators<seqan3::free_ends_at> = true;
81 
82 } // namespace seqan3
83 
84 namespace seqan3::detail
85 {
90 template <free_ends_at val = free_ends_at::none>
91 struct align_config_sequence_ends
92 {
94  static constexpr free_ends_at value{val};
95 };
96 
100 struct align_config_sequence_ends_deferred : public detail::deferred_config_element_base<align_config_sequence_ends_deferred>
101 {
103  free_ends_at value{};
104 
113  template <typename fn_t, typename configuration_t>
114  constexpr auto invoke(fn_t && fn, configuration_t && cfg) const
116  requires detail::is_algorithm_configuration_v<remove_cvref_t<configuration_t>>
118  {
119  switch (static_cast<uint8_t>(value))
120  {
121  case 0b0000: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
122  align_config_sequence_ends<static_cast<free_ends_at>(0b0000)>{}));
123 
124  case 0b0001: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
125  align_config_sequence_ends<static_cast<free_ends_at>(0b0001)>{}));
126 
127  case 0b0010: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
128  align_config_sequence_ends<static_cast<free_ends_at>(0b0010)>{}));
129 
130  case 0b0011: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
131  align_config_sequence_ends<static_cast<free_ends_at>(0b0011)>{}));
132 
133  case 0b0100: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
134  align_config_sequence_ends<static_cast<free_ends_at>(0b0100)>{}));
135 
136  case 0b0101: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
137  align_config_sequence_ends<static_cast<free_ends_at>(0b0101)>{}));
138 
139  case 0b0110: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
140  align_config_sequence_ends<static_cast<free_ends_at>(0b0110)>{}));
141 
142  case 0b0111: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
143  align_config_sequence_ends<static_cast<free_ends_at>(0b0111)>{}));
144 
145  case 0b1000: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
146  align_config_sequence_ends<static_cast<free_ends_at>(0b1000)>{}));
147 
148  case 0b1001: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
149  align_config_sequence_ends<static_cast<free_ends_at>(0b1001)>{}));
150 
151  case 0b1010: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
152  align_config_sequence_ends<static_cast<free_ends_at>(0b1010)>{}));
153 
154  case 0b1011: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
155  align_config_sequence_ends<static_cast<free_ends_at>(0b1011)>{}));
156 
157  case 0b1100: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
158  align_config_sequence_ends<static_cast<free_ends_at>(0b1100)>{}));
159 
160  case 0b1101: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
161  align_config_sequence_ends<static_cast<free_ends_at>(0b1101)>{}));
162 
163  case 0b1110: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
164  align_config_sequence_ends<static_cast<free_ends_at>(0b1110)>{}));
165 
166  case 0b1111: return fn(std::forward<configuration_t>(cfg).replace_with(*this,
167  align_config_sequence_ends<static_cast<free_ends_at>(0b1111)>{}));
168 
169  default: throw std::invalid_argument("Enum value out of bounds for seqan3::free_ends_at.");
170  }
171  }
172 };
173 
178 template <free_ends_at val>
179 struct align_config_sequence_ends_adaptor : public configuration_fn_base<align_config_sequence_ends_adaptor<val>>
180 {
187  template <typename configuration_type>
189  requires is_algorithm_configuration_v<remove_cvref_t<configuration_type>>
191  constexpr auto invoke(configuration_type && cfg, free_ends_at const _val) const
192  {
193  static_assert(is_valid_alignment_configuration_v<align_cfg::id::sequence_ends, remove_cvref_t<configuration_type>>,
194  SEQAN3_INVALID_CONFIG(align_cfg::id::sequence_ends));
195 
196  align_config_sequence_ends_deferred tmp;
197  tmp.value = _val;
198  return std::forward<configuration_type>(cfg).push_front(std::move(tmp));
199  }
200 
207  template <typename configuration_type>
209  requires is_algorithm_configuration_v<remove_cvref_t<configuration_type>>
211  constexpr auto invoke(configuration_type && cfg) const
212  {
213  static_assert(is_valid_alignment_configuration_v<align_cfg::id::sequence_ends, remove_cvref_t<configuration_type>>,
214  SEQAN3_INVALID_CONFIG(align_cfg::id::sequence_ends));
215 
216  return std::forward<configuration_type>(cfg).push_front(align_config_sequence_ends<val>{});
217  }
218 };
219 
222 template <>
223 struct on_align_config<align_cfg::id::sequence_ends>
224 {
228  template <config_element_concept cfg>
229  using invoke = std::conditional_t<is_value_specialisation_of_v<cfg, align_config_sequence_ends>,
230  std::true_type,
231  typename std::is_same<cfg, align_config_sequence_ends_deferred>::type>;
232 };
233 
238 template <free_ends_at val>
239 struct align_config_type_to_id<align_config_sequence_ends<val>>
240 {
242  static constexpr align_cfg::id value = align_cfg::id::sequence_ends;
243 };
244 
248 template <>
249 struct align_config_type_to_id<align_config_sequence_ends_deferred>
250 {
252  static constexpr align_cfg::id value = align_cfg::id::sequence_ends;
253 };
254 
255 } // namespace seqan3::detail
256 
257 namespace seqan3::align_cfg
258 {
259 
267 template <free_ends_at val = free_ends_at::none>
268 inline constexpr detail::align_config_sequence_ends_adaptor<val> sequence_ends;
269 
270 } // namespace seqan3::align_cfg
Provides seqan3::add_enum_bitwise_operators.
Identifier for free ends configuration.
Provides seqan3::type_list and auxiliary metafunctions.
Continuous gaps in the beginning and end of both sequences are not scored.
No flag is set.
Definition: debug_stream.hpp:65
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:58
A special sub namespace for the alignment configurations.
Definition: align_config_band.hpp:151
Continuous gaps in the beginning of the second sequence are not scored.
constexpr detail::align_config_sequence_ends_adaptor< val > sequence_ends
A configuration adaptor for gaps at the sequence ends.
Definition: align_config_sequence_ends.hpp:268
Provides functionality to access get function by enum values.
Continuous gaps in the beginning and end of the second sequence are not scored.
Continuous gaps at the end of the second sequence are not scored.
Continuous gaps in the beginning and end of the first sequence are not scored.
std::remove_cv_t< std::remove_reference_t< t > > remove_cvref_t
Return the input type with const, volatile and references removed [Type metafunction].
Definition: basic.hpp:64
Definition: aligned_sequence_concept.hpp:288
Continuous gaps at the end of the first sequence are not scored.
id
Specifies an id for every configuration element.
Definition: utility.hpp:66
Meta-Header for components of the algorithm submodule.
Continuous gaps in the beginning of the first sequence are not scored.
free_ends_at
Enum class for all supported sequence ends specifications.
Definition: align_config_sequence_ends.hpp:57