SeqAn3  3.2.0
The Modern C++ library for sequence analysis.
detail/record.hpp
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2022, 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 
15 #pragma once
16 
17 #include <ranges>
18 
19 #include <seqan3/io/record.hpp>
23 
24 namespace seqan3::detail
25 {
26 
27 // ----------------------------------------------------------------------------
28 // Fields
29 // ----------------------------------------------------------------------------
30 
34 template <typename t>
35 concept fields_specialisation = is_value_specialisation_of_v<t, fields>;
36 
37 // ----------------------------------------------------------------------------
38 // select_types_with_ids
39 // ----------------------------------------------------------------------------
40 
61 template <typename field_types,
62  typename field_types_as_ids,
63  typename selected_field_ids,
64  size_t field_no = 0,
65  typename... return_types>
66 struct select_types_with_ids // unconstrained template is recursion anchor
67 {
69  using type = type_list<return_types...>;
70 };
71 
75 template <typename field_types,
76  typename field_types_as_ids,
77  typename selected_field_ids,
78  size_t field_no = 0,
79  typename... return_types>
80 using select_types_with_ids_t =
81  typename select_types_with_ids<field_types, field_types_as_ids, selected_field_ids, field_no, return_types...>::
82  type;
84 template <typename field_types,
85  typename field_types_as_ids,
86  typename selected_field_ids,
87  size_t field_no,
88  typename... return_types>
89  requires (field_no < selected_field_ids::as_array.size()) // perform recursion while not at end
90 struct select_types_with_ids<field_types, field_types_as_ids, selected_field_ids, field_no, return_types...>
91 {
92  static_assert(field_types_as_ids::contains(selected_field_ids::as_array[field_no]),
93  "You selected a field that was not in field_types_as_ids.");
94 
95  // call this type trait again, but increase index by one and append a type to the returned type list.
96  using type = select_types_with_ids_t<
97  field_types,
98  field_types_as_ids,
99  selected_field_ids,
100  field_no + 1,
101  return_types...,
102  list_traits::at<field_types_as_ids::index_of(selected_field_ids::as_array[field_no]), field_types>>;
103 };
105 
106 // ----------------------------------------------------------------------------
107 // get_or_ignore
108 // ----------------------------------------------------------------------------
109 
112 template <field f, typename field_types, typename field_ids>
113 auto & get_or_ignore(record<field_types, field_ids> & r)
114 {
115  if constexpr (field_ids::contains(f))
116  return std::get<field_ids::index_of(f)>(r);
117  else
118  return std::ignore;
119 }
120 
122 template <field f, typename field_types, typename field_ids>
123 auto const & get_or_ignore(record<field_types, field_ids> const & r)
124 {
125  if constexpr (field_ids::contains(f))
126  return std::get<field_ids::index_of(f)>(r);
127  else
128  return std::ignore;
129 }
130 
132 template <size_t i, tuple_like tuple_t>
133 auto & get_or_ignore(tuple_t & t)
134 {
135  if constexpr (i < std::tuple_size_v<tuple_t>)
136  return std::get<i>(t);
137  else
138  return std::ignore;
139 }
140 
142 template <size_t i, tuple_like tuple_t>
143 auto const & get_or_ignore(tuple_t const & t)
144 {
145  if constexpr (i < std::tuple_size_v<tuple_t>)
146  return std::get<i>(t);
147  else
148  return std::ignore;
149 }
150 
151 // ----------------------------------------------------------------------------
152 // get_or
153 // ----------------------------------------------------------------------------
154 
157 template <field f, typename field_types, typename field_ids, typename or_type>
158 decltype(auto) get_or(record<field_types, field_ids> & r, or_type && or_value)
159 {
160  if constexpr (field_ids::contains(f))
161  return std::get<field_ids::index_of(f)>(r);
162  else
163  return std::forward<or_type>(or_value);
164 }
165 
167 template <field f, typename field_types, typename field_ids, typename or_type>
168 decltype(auto) get_or(record<field_types, field_ids> const & r, or_type && or_value)
169 {
170  if constexpr (field_ids::contains(f))
171  return std::get<field_ids::index_of(f)>(r);
172  else
173  return std::forward<or_type>(or_value);
174 }
175 
177 template <size_t i, typename or_type, typename... types>
178 decltype(auto) get_or(std::tuple<types...> & t, or_type && or_value)
179 {
180  if constexpr (i < sizeof...(types))
181  return std::get<i>(t);
182  else
183  return std::forward<or_type>(or_value);
184 }
185 
187 template <size_t i, typename or_type, typename... types>
188 decltype(auto) get_or(std::tuple<types...> const & t, or_type && or_value)
189 {
190  if constexpr (i < sizeof...(types))
191  return std::get<i>(t);
192  else
193  return std::forward<or_type>(or_value);
194 }
195 
196 // ----------------------------------------------------------------------------
197 // range_wrap_ignore
198 // ----------------------------------------------------------------------------
199 
202 template <std::ranges::input_range rng_t>
203 inline auto & range_wrap_ignore(rng_t & range)
204 {
205  return range;
206 }
207 
215 inline auto range_wrap_ignore(ignore_t const &)
216 {
217  return views::repeat(std::ignore);
218 }
219 
220 } // namespace seqan3::detail
requires requires
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition: alphabet/concept.hpp:164
requires constexpr seqan3::detail::template_specialisation_of< list_t, seqan3::type_list > bool contains
Whether a type occurs in a type list or not.
Definition: type_list/traits.hpp:252
constexpr size_t size
The size of a type pack.
Definition: type_pack/traits.hpp:146
constexpr detail::repeat_fn repeat
A view factory that repeats a given value infinitely.
Definition: repeat.hpp:342
SeqAn specific customisations in the standard namespace.
The <ranges> header from C++20's standard library.
Provides the seqan3::record template and the seqan3::field enum.
Provides the seqan3::views::repeat.
Provides traits for seqan3::type_list.
Provides seqan3::tuple_like.