SeqAn3 3.4.3-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
record.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2026 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2026 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <limits>
13#include <tuple>
14#include <vector>
15
17
18namespace seqan3
19{
20
21// ----------------------------------------------------------------------------
22// enum field
23// ----------------------------------------------------------------------------
24
60enum class field
61{
62 // Fields used in multiple contexts ........................................
63 seq,
64 id,
65 qual,
66
67 offset,
68
69 // Fields unique to structure io ...........................................
70 bpp,
71 structure,
73 energy,
74 react,
75 react_err,
76 comment,
77
78 // Fields unique to alignment io ...........................................
79 alignment,
80 ref_id,
81 ref_seq,
84
85 flag,
86 mate,
87 mapq,
88 cigar,
89 tags,
90
91 bit_score,
92 evalue,
93
94 // User defined field aliases .. ...........................................
105};
106
107// ----------------------------------------------------------------------------
108// fields
109// ----------------------------------------------------------------------------
110
124template <field... fs>
125struct fields
126{
129 static constexpr std::array<field, sizeof...(fs)> as_array{fs...};
130
132 static constexpr size_t npos = std::numeric_limits<size_t>::max();
133
135 static constexpr size_t size = sizeof...(fs);
136
138 static constexpr size_t index_of(field f)
139 {
140 for (size_t i = 0; i < sizeof...(fs); ++i)
141 if (as_array[i] == f)
142 return i;
143 return npos;
144 }
145
147 static constexpr bool contains(field f)
148 {
149 return index_of(f) != npos;
150 }
151
152 static_assert(
153 []() constexpr
154 {
155 for (size_t i = 0; i < as_array.size(); ++i)
156 for (size_t j = i + 1; j < as_array.size(); ++j)
157 if (as_array[i] == as_array[j])
158 return false;
159
160 return true;
161 }(),
162 "You may not include a field twice into fields<>.");
163};
164
165// ----------------------------------------------------------------------------
166// record
167// ----------------------------------------------------------------------------
168
189template <typename field_types, typename field_ids>
190struct record : detail::transfer_template_args_onto_t<field_types, std::tuple>
191{
192public:
194 using base_type = detail::transfer_template_args_onto_t<field_types, std::tuple>;
195
196private:
198 template <typename t>
199 requires requires (t & v) { v.clear(); }
200 static constexpr void clear_element(t & v) noexcept(noexcept(v.clear()))
201 {
202 v.clear();
203 }
204
206 template <typename t>
207 static constexpr void clear_element(t & v) noexcept(noexcept(std::declval<t &>() = t{}))
208 {
209 v = {};
210 }
211
213 static constexpr auto expander = [](auto &... args)
214 {
215 (clear_element(args), ...);
216 };
217
219 base_type & as_base() noexcept
220 {
221 return *this;
222 }
223
224public:
228 record() = default;
229 record(record const &) = default;
230 record & operator=(record const &) = default;
231 record(record &&) = default;
232 record & operator=(record &&) = default;
233 ~record() = default;
234
236 using base_type::base_type;
238
239 static_assert(field_types::size() == field_ids::as_array.size(),
240 "You must give as many IDs as types to seqan3::record.");
241
243 void clear() noexcept(noexcept(std::apply(expander, std::declval<record &>().as_base())))
244 {
245 // PR2165 / __cpp_lib_tuple_like (C++23): std::apply requires tuple-like.
246 // In C++23, this means std::array, std::pair, std::tuple, and std::ranges::subranges. Nothing else.
247 // https://en.cppreference.com/w/cpp/utility/tuple/tuple-like
248 std::apply(expander, as_base());
249 }
250
251protected:
253
255 template <field f>
256 using field_constant = std::integral_constant<field, f>;
257
259 template <field f, typename tuple_t>
260 static decltype(auto) get_impl(field_constant<f>, tuple_t && record_as_tuple)
261 {
262 static_assert(field_ids::contains(f), "The record does not contain the field you wish to retrieve.");
263 return std::get<field_ids::index_of(f)>(std::forward<tuple_t>(record_as_tuple));
264 }
265};
266
267} // namespace seqan3
268
269namespace std
270{
271
277template <typename field_types, typename field_ids>
278struct tuple_size<seqan3::record<field_types, field_ids>> :
279 tuple_size<typename seqan3::record<field_types, field_ids>::base_type>
280{};
281
287template <size_t elem_no, typename field_types, typename field_ids>
288struct tuple_element<elem_no, seqan3::record<field_types, field_ids>> :
289 tuple_element<elem_no, typename seqan3::record<field_types, field_ids>::base_type>
290{};
291
292} // namespace std
T apply(T... args)
The seqan3::cigar semialphabet pairs a counter with a seqan3::cigar::operation letter.
Definition alphabet/cigar/cigar.hpp:57
A "pretty printer" for most SeqAn data structures and related types.
Definition debug_stream_type.hpp:79
field
An enumerator for the fields used in file formats.
Definition record.hpp:61
@ energy
Energy of a folded sequence, represented by one float number.
@ comment
Comment field of arbitrary content, usually a string.
@ structure
Fixed interactions, usually a string of structure alphabet characters.
@ bpp
Base pair probability matrix of interactions, usually a matrix of float numbers.
@ react
Reactivity values of the sequence characters given in a vector of float numbers.
@ flag
The alignment flag (bit information), uint16_t value.
@ react_err
Reactivity error values given in a vector corresponding to seqan3::field::react.
@ ref_offset
Sequence (seqan3::field::ref_seq) relative start position (0-based), unsigned value.
@ ref_seq
The (reference) "sequence" information, usually a range of nucleotides or amino acids.
@ alignment
The (pairwise) alignment stored in an object that models seqan3::detail::pairwise_alignment.
@ mapq
The mapping quality of the seqan3::field::seq alignment, usually a Phred-scaled score.
@ user_defined_2
Identifier for user defined file formats and specialisations.
@ user_defined_5
Identifier for user defined file formats and specialisations.
@ bit_score
The bit score (statistical significance indicator), unsigned value.
@ user_defined_0
Identifier for user defined file formats and specialisations.
@ user_defined_8
Identifier for user defined file formats and specialisations.
@ user_defined_3
Identifier for user defined file formats and specialisations.
@ offset
Sequence (seqan3::field::seq) relative start position (0-based), unsigned value.
@ mate
The mate pair information given as a std::tuple of reference name, offset and template length.
@ header_ptr
A pointer to the seqan3::sam_file_header object storing header information.
@ user_defined_7
Identifier for user defined file formats and specialisations.
@ user_defined_4
Identifier for user defined file formats and specialisations.
@ ref_id
The identifier of the (reference) sequence that seqan3::field::seq was aligned to.
@ structured_seq
Sequence and fixed interactions combined in one range.
@ evalue
The e-value (length normalized bit score), double value.
@ id
The identifier, usually a string.
@ user_defined_6
Identifier for user defined file formats and specialisations.
@ tags
The optional tags in the SAM format, stored in a dictionary.
@ user_defined_1
Identifier for user defined file formats and specialisations.
@ user_defined_9
Identifier for user defined file formats and specialisations.
@ seq
The "sequence", usually a range of nucleotides or amino acids.
@ qual
The qualities, usually in Phred score notation.
T max(T... args)
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
SeqAn specific customisations in the standard namespace.
A class template that holds a choice of seqan3::field.
Definition record.hpp:126
The class template that file records are based on; behaves like a std::tuple.
Definition record.hpp:191
void clear() noexcept(noexcept(std::apply(expander, std::declval< record & >().as_base())))
Clears containers that provide .clear() and (re-)initialises all other elements with = {}.
Definition record.hpp:243
record(record &&)=default
Defaulted.
~record()=default
Defaulted.
detail::transfer_template_args_onto_t< field_types, std::tuple > base_type
A specialisation of std::tuple.
Definition record.hpp:194
record & operator=(record const &)=default
Defaulted.
record()=default
Defaulted.
record & operator=(record &&)=default
Defaulted.
record(record const &)=default
Defaulted.
Provides type traits for working with templates.
Hide me