SeqAn3 3.1.0
The Modern C++ library for sequence analysis.
sam_tag_dictionary.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
13#pragma once
14
15#include <seqan3/std/concepts>
16#include <map>
17#include <variant>
18
23
24namespace seqan3::detail
25{
28using sam_tag_variant = std::variant<char, int32_t, float, std::string,
34
37char constexpr sam_tag_type_char[12] = {'A', 'i', 'f', 'Z', 'H', 'B', 'B', 'B', 'B', 'B', 'B', 'B'};
40char constexpr sam_tag_type_char_extra[12] = {'\0', '\0', '\0', '\0', '\0', 'c', 'C', 's', 'S', 'i', 'I', 'f'};
41}
42
43namespace seqan3
44{
45
46inline namespace literals
47{
48
69#ifdef __cpp_nontype_template_parameter_class
70template <small_string<2> str> // TODO: better handling if too large string is provided?
71constexpr uint16_t operator""_tag()
72{
73#else // GCC/Clang extension
74#pragma GCC diagnostic push
75#pragma GCC diagnostic ignored "-Wpedantic"
76template <typename char_t, char_t ...s>
77constexpr uint16_t operator""_tag()
78{
79 static_assert(std::same_as<char_t, char>, "Illegal SAM tag: Type must be char.");
80 constexpr small_string<sizeof...(s)> str{std::array<char, sizeof...(s)>{s...}};
81#pragma GCC diagnostic pop
82#endif
83
84 static_assert(str.size() == 2, "Illegal SAM tag: Exactly two characters must be given.");
85
86 char constexpr char0 = str[0];
87 char constexpr char1 = str[1];
88
89 static_assert((is_alpha(char0) && is_alnum(char1)),
90 "Illegal SAM tag: a SAM tag must match /[A-Za-z][A-Za-z0-9]/.");
91
92 return static_cast<uint16_t>(char0) * 256 + static_cast<uint16_t>(char1);
93}
95
96} // inline namespace literals
97
175template <uint16_t tag_value>
177{
180};
181
184template <uint16_t tag_value>
186
188template <> struct sam_tag_type<"AM"_tag> { using type = int32_t; };
189template <> struct sam_tag_type<"AS"_tag> { using type = int32_t; };
190template <> struct sam_tag_type<"BC"_tag> { using type = std::string; };
191template <> struct sam_tag_type<"BQ"_tag> { using type = std::string; };
192template <> struct sam_tag_type<"BZ"_tag> { using type = std::string; };
193template <> struct sam_tag_type<"CB"_tag> { using type = std::string; };
194template <> struct sam_tag_type<"CC"_tag> { using type = std::string; };
195template <> struct sam_tag_type<"CG"_tag> { using type = std::vector<int32_t>; };
196template <> struct sam_tag_type<"CM"_tag> { using type = int32_t; };
197template <> struct sam_tag_type<"CO"_tag> { using type = std::string; };
198template <> struct sam_tag_type<"CP"_tag> { using type = int32_t; };
199template <> struct sam_tag_type<"CQ"_tag> { using type = std::string; };
200template <> struct sam_tag_type<"CR"_tag> { using type = std::string; };
201template <> struct sam_tag_type<"CS"_tag> { using type = std::string; };
202template <> struct sam_tag_type<"CT"_tag> { using type = std::string; };
203template <> struct sam_tag_type<"CY"_tag> { using type = std::string; };
204template <> struct sam_tag_type<"E2"_tag> { using type = std::string; };
205template <> struct sam_tag_type<"FI"_tag> { using type = int32_t; };
206template <> struct sam_tag_type<"FS"_tag> { using type = std::string; };
207template <> struct sam_tag_type<"FZ"_tag> { using type = std::vector<uint16_t>; };
208
209// template <> struct sam_tag_type<"GC"_tag> {};
210// template <> struct sam_tag_type<"GQ"_tag> {};
211// template <> struct sam_tag_type<"GS"_tag> {};
212
213template <> struct sam_tag_type<"H0"_tag> { using type = int32_t; };
214template <> struct sam_tag_type<"H1"_tag> { using type = int32_t; };
215template <> struct sam_tag_type<"H2"_tag> { using type = int32_t; };
216template <> struct sam_tag_type<"HI"_tag> { using type = int32_t; };
217template <> struct sam_tag_type<"IH"_tag> { using type = int32_t; };
218template <> struct sam_tag_type<"LB"_tag> { using type = std::string; };
219template <> struct sam_tag_type<"MC"_tag> { using type = std::string; };
220template <> struct sam_tag_type<"MD"_tag> { using type = std::string; };
221
222// template <> struct sam_tag_type<"MF"_tag> {};
223
224template <> struct sam_tag_type<"MI"_tag> { using type = std::string; };
225template <> struct sam_tag_type<"MQ"_tag> { using type = int32_t; };
226template <> struct sam_tag_type<"NH"_tag> { using type = int32_t; };
227template <> struct sam_tag_type<"NM"_tag> { using type = int32_t; };
228template <> struct sam_tag_type<"OC"_tag> { using type = std::string; };
229template <> struct sam_tag_type<"OP"_tag> { using type = int32_t; };
230template <> struct sam_tag_type<"OQ"_tag> { using type = std::string; };
231template <> struct sam_tag_type<"OX"_tag> { using type = std::string; };
232template <> struct sam_tag_type<"PG"_tag> { using type = std::string; };
233template <> struct sam_tag_type<"PQ"_tag> { using type = int32_t; };
234template <> struct sam_tag_type<"PT"_tag> { using type = std::string; };
235template <> struct sam_tag_type<"PU"_tag> { using type = std::string; };
236template <> struct sam_tag_type<"Q2"_tag> { using type = std::string; };
237template <> struct sam_tag_type<"QT"_tag> { using type = std::string; };
238template <> struct sam_tag_type<"QX"_tag> { using type = std::string; };
239template <> struct sam_tag_type<"R2"_tag> { using type = std::string; };
240template <> struct sam_tag_type<"RG"_tag> { using type = std::string; };
241template <> struct sam_tag_type<"RT"_tag> { using type = std::string; };
242template <> struct sam_tag_type<"RX"_tag> { using type = std::string; };
243
244// template <> struct sam_tag_type<"S2"_tag> {};
245
246template <> struct sam_tag_type<"SA"_tag> { using type = std::string; };
247template <> struct sam_tag_type<"SM"_tag> { using type = int32_t; };
248
249// template <> struct sam_tag_type<"SQ"_tag> {};
250
251template <> struct sam_tag_type<"TC"_tag> { using type = int32_t; };
252template <> struct sam_tag_type<"U2"_tag> { using type = std::string; };
253template <> struct sam_tag_type<"UQ"_tag> { using type = int32_t; };
255
336class sam_tag_dictionary : public std::map<uint16_t, detail::sam_tag_variant>
337{
338private:
341
342public:
345
362 template <uint16_t tag>
364 requires (!std::same_as<sam_tag_type_t<tag>, variant_type>)
366 auto & get() &
367 {
368 if ((*this).count(tag) == 0)
369 (*this)[tag] = sam_tag_type_t<tag>{}; // set correct type if tag is not set yet on
370
371 return std::get<sam_tag_type_t<tag>>((*this)[tag]);
372 }
373
375 template <uint16_t tag>
377 requires (!std::same_as<sam_tag_type_t<tag>, variant_type>)
379 auto && get() &&
380 {
381 if ((*this).count(tag) == 0)
382 (*this)[tag] = sam_tag_type_t<tag>{}; // set correct type if tag is not set yet on
383
384 return std::get<sam_tag_type_t<tag>>(std::move((*this)[tag]));
385 }
386
389 template <uint16_t tag>
391 requires (!std::same_as<sam_tag_type_t<tag>, variant_type>)
393 auto const & get() const &
394 {
395 return std::get<sam_tag_type_t<tag>>((*this).at(tag));
396 }
397
400 template <uint16_t tag>
402 requires (!std::same_as<sam_tag_type_t<tag>, variant_type>)
404 auto const && get() const &&
405 {
406 return std::get<sam_tag_type_t<tag>>(std::move((*this).at(tag)));
407 }
409};
410
411} // namespace seqan3
The SAM tag dictionary class that stores all optional SAM fields.
Definition: sam_tag_dictionary.hpp:337
auto && get() &&
Uses std::map::operator[] for access and default initializes new keys.
Definition: sam_tag_dictionary.hpp:379
auto const & get() const &
Uses std::map::at() for access and throws when the key is unknown.
Definition: sam_tag_dictionary.hpp:393
auto const && get() const &&
Uses std::map::at() for access and throws when the key is unknown.
Definition: sam_tag_dictionary.hpp:404
auto & get() &
Uses std::map::operator[] for access and default initializes new keys.
Definition: sam_tag_dictionary.hpp:366
Implements a small string that can be used for compile time computations.
Definition: small_string.hpp:44
The <concepts> header from C++20's standard library.
Provides concepts for core language types and relations that don't have concepts in C++20 (yet).
constexpr auto is_alnum
Checks whether c is a alphanumeric character.
Definition: predicate.hpp:202
constexpr auto is_alpha
Checks whether c is a alphabetical character.
Definition: predicate.hpp:221
The main SeqAn3 namespace.
Definition: cigar_operation_table.hpp:2
Provides character predicates for tokenisation.
A constexpr string implementation to manipulate string literals at compile time.
The generic base class.
Definition: sam_tag_dictionary.hpp:177
typename sam_tag_type< tag_value >::type sam_tag_type_t
Short cut helper for seqan3::sam_tag_type::type.
Definition: sam_tag_dictionary.hpp:185
Provides type traits for working with templates.