SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
sam_tag_dictionary.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 
13 #pragma once
14 
15 #include <map>
16 #include <variant>
17 
22 #include <seqan3/std/concepts>
23 
24 namespace seqan3::detail
25 {
28  using sam_tag_variant = std::variant<char, int32_t, float, std::string,
33 
35  char constexpr sam_tag_type_char[11] = {'A', 'i', 'f', 'Z', 'B', 'B', 'B', 'B', 'B', 'B', 'B'};
37  char constexpr sam_tag_type_char_extra[11] = {'\0', '\0', '\0', '\0', 'c', 'C', 's', 'S', 'i', 'I', 'f'};
38 }
39 
40 namespace seqan3
41 {
42 
63 #ifdef __cpp_nontype_template_parameter_class
64 template <small_string<2> str> // TODO: better handling if too large string is provided?
65 constexpr uint16_t operator""_tag()
66 {
67 #else // GCC/Clang extension
68 #pragma GCC diagnostic push
69 #pragma GCC diagnostic ignored "-Wpedantic"
70 template <typename char_t, char_t ...s>
71 constexpr uint16_t operator""_tag()
72 {
73  static_assert(std::same_as<char_t, char>, "Illegal SAM tag: Type must be char.");
74  constexpr small_string<sizeof...(s)> str{std::array<char, sizeof...(s)>{s...}};
75 #pragma GCC diagnostic pop
76 #endif
77 
78  static_assert(str.size() == 2, "Illegal SAM tag: Exactly two characters must be given.");
79 
80  char constexpr char0 = str[0];
81  char constexpr char1 = str[1];
82 
83  static_assert((is_alpha(char0) && is_alnum(char1)),
84  "Illegal SAM tag: a SAM tag must match /[A-Za-z][A-Za-z0-9]/.");
85 
86  return static_cast<uint16_t>(char0) * 256 + static_cast<uint16_t>(char1);
87 }
88 
165 template <uint16_t tag_value>
167 {
170 };
171 
174 template <uint16_t tag_value>
176 
178 template <> struct sam_tag_type<"AM"_tag> { using type = int32_t; };
179 template <> struct sam_tag_type<"AS"_tag> { using type = int32_t; };
180 template <> struct sam_tag_type<"BC"_tag> { using type = std::string; };
181 template <> struct sam_tag_type<"BQ"_tag> { using type = std::string; };
182 template <> struct sam_tag_type<"BZ"_tag> { using type = std::string; };
183 template <> struct sam_tag_type<"CB"_tag> { using type = std::string; };
184 template <> struct sam_tag_type<"CC"_tag> { using type = std::string; };
185 template <> struct sam_tag_type<"CG"_tag> { using type = std::vector<int32_t>; };
186 template <> struct sam_tag_type<"CM"_tag> { using type = int32_t; };
187 template <> struct sam_tag_type<"CO"_tag> { using type = std::string; };
188 template <> struct sam_tag_type<"CP"_tag> { using type = int32_t; };
189 template <> struct sam_tag_type<"CQ"_tag> { using type = std::string; };
190 template <> struct sam_tag_type<"CR"_tag> { using type = std::string; };
191 template <> struct sam_tag_type<"CS"_tag> { using type = std::string; };
192 template <> struct sam_tag_type<"CT"_tag> { using type = std::string; };
193 template <> struct sam_tag_type<"CY"_tag> { using type = std::string; };
194 template <> struct sam_tag_type<"E2"_tag> { using type = std::string; };
195 template <> struct sam_tag_type<"FI"_tag> { using type = int32_t; };
196 template <> struct sam_tag_type<"FS"_tag> { using type = std::string; };
197 template <> struct sam_tag_type<"FZ"_tag> { using type = std::vector<uint16_t>; };
198 
199 // template <> struct sam_tag_type<"GC"_tag> {};
200 // template <> struct sam_tag_type<"GQ"_tag> {};
201 // template <> struct sam_tag_type<"GS"_tag> {};
202 
203 template <> struct sam_tag_type<"H0"_tag> { using type = int32_t; };
204 template <> struct sam_tag_type<"H1"_tag> { using type = int32_t; };
205 template <> struct sam_tag_type<"H2"_tag> { using type = int32_t; };
206 template <> struct sam_tag_type<"HI"_tag> { using type = int32_t; };
207 template <> struct sam_tag_type<"IH"_tag> { using type = int32_t; };
208 template <> struct sam_tag_type<"LB"_tag> { using type = std::string; };
209 template <> struct sam_tag_type<"MC"_tag> { using type = std::string; };
210 template <> struct sam_tag_type<"MD"_tag> { using type = std::string; };
211 
212 // template <> struct sam_tag_type<"MF"_tag> {};
213 
214 template <> struct sam_tag_type<"MI"_tag> { using type = std::string; };
215 template <> struct sam_tag_type<"MQ"_tag> { using type = int32_t; };
216 template <> struct sam_tag_type<"NH"_tag> { using type = int32_t; };
217 template <> struct sam_tag_type<"NM"_tag> { using type = int32_t; };
218 template <> struct sam_tag_type<"OC"_tag> { using type = std::string; };
219 template <> struct sam_tag_type<"OP"_tag> { using type = int32_t; };
220 template <> struct sam_tag_type<"OQ"_tag> { using type = std::string; };
221 template <> struct sam_tag_type<"OX"_tag> { using type = std::string; };
222 template <> struct sam_tag_type<"PG"_tag> { using type = std::string; };
223 template <> struct sam_tag_type<"PQ"_tag> { using type = int32_t; };
224 template <> struct sam_tag_type<"PT"_tag> { using type = std::string; };
225 template <> struct sam_tag_type<"PU"_tag> { using type = std::string; };
226 template <> struct sam_tag_type<"Q2"_tag> { using type = std::string; };
227 template <> struct sam_tag_type<"QT"_tag> { using type = std::string; };
228 template <> struct sam_tag_type<"QX"_tag> { using type = std::string; };
229 template <> struct sam_tag_type<"R2"_tag> { using type = std::string; };
230 template <> struct sam_tag_type<"RG"_tag> { using type = std::string; };
231 template <> struct sam_tag_type<"RT"_tag> { using type = std::string; };
232 template <> struct sam_tag_type<"RX"_tag> { using type = std::string; };
233 
234 // template <> struct sam_tag_type<"S2"_tag> {};
235 
236 template <> struct sam_tag_type<"SA"_tag> { using type = std::string; };
237 template <> struct sam_tag_type<"SM"_tag> { using type = int32_t; };
238 
239 // template <> struct sam_tag_type<"SQ"_tag> {};
240 
241 template <> struct sam_tag_type<"TC"_tag> { using type = int32_t; };
242 template <> struct sam_tag_type<"U2"_tag> { using type = std::string; };
243 template <> struct sam_tag_type<"UQ"_tag> { using type = int32_t; };
245 
324 class sam_tag_dictionary : public std::map<uint16_t, detail::sam_tag_variant>
325 {
326 private:
329 
330 public:
333 
349  template <uint16_t tag>
354  auto & get() &
355  {
356  if ((*this).count(tag) == 0)
357  (*this)[tag] = sam_tag_type_t<tag>{}; // set correct type if tag is not set yet on
358 
359  return std::get<sam_tag_type_t<tag>>((*this)[tag]);
360  }
361 
363  template <uint16_t tag>
367  auto && get() &&
368  {
369  if ((*this).count(tag) == 0)
370  (*this)[tag] = sam_tag_type_t<tag>{}; // set correct type if tag is not set yet on
371 
372  return std::get<sam_tag_type_t<tag>>(std::move((*this)[tag]));
373  }
374 
377  template <uint16_t tag>
381  auto const & get() const &
382  {
383  return std::get<sam_tag_type_t<tag>>((*this).at(tag));
384  }
385 
388  template <uint16_t tag>
392  auto const && get() const &&
393  {
394  return std::get<sam_tag_type_t<tag>>(std::move((*this).at(tag)));
395  }
397 };
398 
399 } // namespace seqan3
seqan3::is_alnum
constexpr auto is_alnum
Checks whether c is a alphanumeric character.
Definition: predicate.hpp:220
seqan3::sam_tag_dictionary::get
auto && get() &&
Uses std::map::operator[] for access and default initializes new keys.
Definition: sam_tag_dictionary.hpp:367
std::string
seqan3::is_alpha
constexpr auto is_alpha
Checks whether c is a alphabetical character.
Definition: predicate.hpp:239
std::vector
seqan3::small_string
Implements a small string that can be used for compile time computations.
Definition: small_string.hpp:42
seqan3::views::move
const auto move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:68
template_inspection.hpp
Provides seqan3::type_list and auxiliary type traits.
seqan3::sam_tag_dictionary::variant_type
detail::sam_tag_variant variant_type
The variant type defining all valid SAM tag field types.
Definition: sam_tag_dictionary.hpp:332
seqan3::sam_tag_type_t
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:175
seqan3::sam_tag_type
The generic base class.
Definition: sam_tag_dictionary.hpp:166
concepts
The Concepts library.
seqan3::sam_tag_type::type
detail::sam_tag_variant type
The type for all unknown tags with no extra overload defaults to an std::variant.
Definition: sam_tag_dictionary.hpp:169
same_as
The concept std::same_as<T, U> is satisfied if and only if T and U denote the same type.
seqan3::sam_tag_dictionary::get
auto & get() &
Uses std::map::operator[] for access and default initializes new keys.
Definition: sam_tag_dictionary.hpp:354
small_string.hpp
A constexpr string implementation to manipulate string literals at compile time.
seqan3::sam_tag_dictionary::get
const auto & get() const &
Uses std::map::at() for access and throws when the key is unknown.
Definition: sam_tag_dictionary.hpp:381
core_language.hpp
Provides concepts for core language types and relations that don't have concepts in C++20 (yet).
std::array
seqan3
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:36
map
seqan3::sam_tag_dictionary
The SAM tag dictionary class that stores all optional SAM fields.
Definition: sam_tag_dictionary.hpp:324
seqan3::sam_tag_dictionary::get
const auto && get() const &&
Uses std::map::at() for access and throws when the key is unknown.
Definition: sam_tag_dictionary.hpp:392
predicate.hpp
Provides character predicates for tokenisation.
variant