SeqAn3  3.0.3
The Modern C++ library for sequence analysis.
record.hpp
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 
15 #pragma once
16 
17 #include <seqan3/std/ranges>
18 
19 #include <seqan3/io/record.hpp>
23 
24 namespace seqan3::detail
25 {
26 
27 // ----------------------------------------------------------------------------
28 // Fields
29 // ----------------------------------------------------------------------------
30 
35 template <typename t>
36 SEQAN3_CONCEPT fields_specialisation = is_value_specialisation_of_v<t, fields>;
37 
38 // ----------------------------------------------------------------------------
39 // select_types_with_ids
40 // ----------------------------------------------------------------------------
41 
62 template <typename field_types,
63  typename field_types_as_ids,
64  typename selected_field_ids,
65  size_t field_no = 0,
66  typename ...return_types>
67 struct select_types_with_ids // unconstrained template is recursion anchor
68 {
70  using type = type_list<return_types...>;
71 };
72 
77 template <typename field_types,
78  typename field_types_as_ids,
79  typename selected_field_ids,
80  size_t field_no = 0,
81  typename ...return_types>
82 using select_types_with_ids_t = typename select_types_with_ids<field_types,
83  field_types_as_ids,
84  selected_field_ids,
85  field_no,
86  return_types...>::type;
88 template <typename field_types,
89  typename field_types_as_ids,
90  typename selected_field_ids,
91  size_t field_no,
92  typename ...return_types>
93  requires (field_no < selected_field_ids::as_array.size()) // perform recursion while not at end
94 struct select_types_with_ids<field_types, field_types_as_ids, selected_field_ids, field_no, return_types...>
95 {
96  static_assert(field_types_as_ids::contains(selected_field_ids::as_array[field_no]),
97  "You selected a field that was not in field_types_as_ids.");
98 
99  // call this type trait again, but increase index by one and append a type to the returned type list.
100  using type = select_types_with_ids_t<field_types,
101  field_types_as_ids,
102  selected_field_ids,
103  field_no + 1,
104  return_types ...,
105  list_traits::at<field_types_as_ids::index_of(
106  selected_field_ids::as_array[field_no]), field_types>>;
107 
108 };
110 
111 
112 // ----------------------------------------------------------------------------
113 // get_or_ignore
114 // ----------------------------------------------------------------------------
115 
120 template <field f, typename field_types, typename field_ids>
121 auto & get_or_ignore(record<field_types, field_ids> & r)
122 {
123  if constexpr (field_ids::contains(f))
124  return std::get<field_ids::index_of(f)>(r);
125  else
126  return std::ignore;
127 }
128 
130 template <field f, typename field_types, typename field_ids>
131 auto const & get_or_ignore(record<field_types, field_ids> const & r)
132 {
133  if constexpr (field_ids::contains(f))
134  return std::get<field_ids::index_of(f)>(r);
135  else
136  return std::ignore;
137 }
138 
140 template <size_t i, tuple_like tuple_t>
141 auto & get_or_ignore(tuple_t & t)
142 {
143  if constexpr (i < std::tuple_size_v<tuple_t>)
144  return std::get<i>(t);
145  else
146  return std::ignore;
147 }
148 
150 template <size_t i, tuple_like tuple_t>
151 auto const & get_or_ignore(tuple_t const & t)
152 {
153  if constexpr (i < std::tuple_size_v<tuple_t>)
154  return std::get<i>(t);
155  else
156  return std::ignore;
157 }
159 
160 
161 // ----------------------------------------------------------------------------
162 // get_or
163 // ----------------------------------------------------------------------------
164 
169 template <field f, typename field_types, typename field_ids, typename or_type>
170 decltype(auto) get_or(record<field_types, field_ids> & r, or_type && or_value)
171 {
172  if constexpr (field_ids::contains(f))
173  return std::get<field_ids::index_of(f)>(r);
174  else
175  return std::forward<or_type>(or_value);
176 }
177 
179 template <field f, typename field_types, typename field_ids, typename or_type>
180 decltype(auto) get_or(record<field_types, field_ids> const & r, or_type && or_value)
181 {
182  if constexpr (field_ids::contains(f))
183  return std::get<field_ids::index_of(f)>(r);
184  else
185  return std::forward<or_type>(or_value);
186 }
187 
189 template <size_t i, typename or_type, typename ...types>
190 decltype(auto) get_or(std::tuple<types...> & t, or_type && or_value)
191 {
192  if constexpr (i < sizeof...(types))
193  return std::get<i>(t);
194  else
195  return std::forward<or_type>(or_value);
196 }
197 
199 template <size_t i, typename or_type, typename ...types>
200 decltype(auto) get_or(std::tuple<types...> const & t, or_type && or_value)
201 {
202  if constexpr (i < sizeof...(types))
203  return std::get<i>(t);
204  else
205  return std::forward<or_type>(or_value);
206 }
208 
209 // ----------------------------------------------------------------------------
210 // range_wrap_ignore
211 // ----------------------------------------------------------------------------
212 
214 template <std::ranges::input_range rng_t>
215 inline auto & range_wrap_ignore(rng_t & range)
216 {
217  return range;
218 }
219 
226 inline auto range_wrap_ignore(ignore_t const &)
227 {
228  return views::repeat(std::ignore);
229 }
230 
231 } // namespace seqan3::detail
constexpr bool contains
Whether a type occurs in a type list or not.
Definition: traits.hpp:231
typename decltype(detail::at< idx >(list_t{}))::type at
Return the type at given index from the type list.
Definition: traits.hpp:260
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:151
constexpr detail::repeat_fn repeat
A view factory that repeats a given value infinitely.
Definition: repeat.hpp:355
SeqAn specific customisations in the standard namespace.
Adaptations of concepts from the Ranges TS.
Provides the seqan3::record template and the seqan3::field enum.
Type that contains multiple types.
Definition: type_list.hpp:29
Provides seqan3::tuple_like.
Provides traits for seqan3::type_list.
Provides the seqan3::views::repeat.