SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
record.hpp
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 
15 #pragma once
16 
19 #include <seqan3/io/record.hpp>
21 #include <seqan3/std/ranges>
22 
23 namespace seqan3::detail
24 {
25 
26 // ----------------------------------------------------------------------------
27 // Fields
28 // ----------------------------------------------------------------------------
29 
34 template <typename t>
35 SEQAN3_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 
76 template <typename field_types,
77  typename field_types_as_ids,
78  typename selected_field_ids,
79  size_t field_no = 0,
80  typename ...return_types>
81 using select_types_with_ids_t = typename select_types_with_ids<field_types,
82  field_types_as_ids,
83  selected_field_ids,
84  field_no,
85  return_types...>::type;
87 template <typename field_types,
88  typename field_types_as_ids,
89  typename selected_field_ids,
90  size_t field_no,
91  typename ...return_types>
92  requires field_no < selected_field_ids::as_array.size() // perform recursion while not at end
93 struct select_types_with_ids<field_types, field_types_as_ids, selected_field_ids, field_no, return_types...>
94 {
95  static_assert(field_types_as_ids::contains(selected_field_ids::as_array[field_no]),
96  "You selected a field that was not in field_types_as_ids.");
97 
98  // call this type trait again, but increase index by one and append a type to the returned type list.
99  using type = select_types_with_ids_t<field_types,
100  field_types_as_ids,
101  selected_field_ids,
102  field_no + 1,
103  return_types ...,
104  list_traits::at<field_types_as_ids::index_of(
105  selected_field_ids::as_array[field_no]), field_types>>;
106 
107 };
109 
110 
111 // ----------------------------------------------------------------------------
112 // get_or_ignore
113 // ----------------------------------------------------------------------------
114 
118 template <field f, typename field_types, typename field_ids>
120 auto & get_or_ignore(record<field_types, field_ids> & r)
121 {
122  if constexpr (field_ids::contains(f))
123  return std::get<field_ids::index_of(f)>(r);
124  else
125  return std::ignore;
126 }
127 
129 template <field f, typename field_types, typename field_ids>
130 auto const & get_or_ignore(record<field_types, field_ids> const & r)
131 {
132  if constexpr (field_ids::contains(f))
133  return std::get<field_ids::index_of(f)>(r);
134  else
135  return std::ignore;
136 }
137 
139 template <size_t i, template <tuple_like ...types_> typename tuple_like_t, typename ...types>
140 auto & get_or_ignore(tuple_like_t<types...> & t)
141 {
142  if constexpr (i < sizeof...(types))
143  return std::get<i>(t);
144  else
145  return std::ignore;
146 }
147 
149 template <size_t i, template <tuple_like ...types_> typename tuple_like_t, typename ...types>
150 auto const & get_or_ignore(tuple_like_t<types...> const & t)
151 {
152  if constexpr (i < sizeof...(types))
153  return std::get<i>(t);
154  else
155  return std::ignore;
156 }
158 
159 
160 // ----------------------------------------------------------------------------
161 // get_or
162 // ----------------------------------------------------------------------------
163 
167 template <field f, typename field_types, typename field_ids, typename or_type>
169 decltype(auto) get_or(record<field_types, field_ids> & r, or_type && or_value)
170 {
171  if constexpr (field_ids::contains(f))
172  return std::get<field_ids::index_of(f)>(r);
173  else
174  return std::forward<or_type>(or_value);
175 }
176 
178 template <field f, typename field_types, typename field_ids, typename or_type>
179 decltype(auto) get_or(record<field_types, field_ids> const & r, or_type && or_value)
180 {
181  if constexpr (field_ids::contains(f))
182  return std::get<field_ids::index_of(f)>(r);
183  else
184  return std::forward<or_type>(or_value);
185 }
186 
188 template <size_t i, typename or_type, typename ...types>
189 decltype(auto) get_or(std::tuple<types...> & t, or_type && or_value)
190 {
191  if constexpr (i < sizeof...(types))
192  return std::get<i>(t);
193  else
194  return std::forward<or_type>(or_value);
195 }
196 
198 template <size_t i, typename or_type, typename ...types>
199 decltype(auto) get_or(std::tuple<types...> const & t, or_type && or_value)
200 {
201  if constexpr (i < sizeof...(types))
202  return std::get<i>(t);
203  else
204  return std::forward<or_type>(or_value);
205 }
207 
208 // ----------------------------------------------------------------------------
209 // range_wrap_ignore
210 // ----------------------------------------------------------------------------
211 
213 template <std::ranges::input_range rng_t>
214 inline auto & range_wrap_ignore(rng_t & range)
215 {
216  return range;
217 }
218 
225 inline auto range_wrap_ignore(ignore_t const &)
226 {
227  return views::repeat(std::ignore);
228 }
229 
230 } // namespace seqan3::detail
seqan3::type_list
meta::list< types... > type_list
Type that contains multiple types, an alias for meta::list.
Definition: type_list.hpp:31
tuple.hpp
Provides seqan3::tuple_like.
repeat.hpp
Provides the views::repeat_view.
record.hpp
Provides the seqan3::record template and the seqan3::field enum.
seqan3::pack_traits::contains
constexpr bool contains
Whether a type occurs in a pack or not.
Definition: traits.hpp:193
seqan3::list_traits::at
typename decltype(detail::at< idx >(list_t{}))::type at
Return the type at given index from the type list.
Definition: traits.hpp:523
tuple_like
Whether a type behaves like a tuple.
ranges
Adaptations of concepts from the Ranges TS.
std
SeqAn specific customisations in the standard namespace.
seqan3::views::repeat
constexpr detail::repeat_fn repeat
A view factory that repeats a given value infinitely.
Definition: repeat.hpp:350
traits.hpp
Provides traits for seqan3::type_list.