SeqAn3 3.1.0
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
24namespace seqan3::detail
25{
26
27// ----------------------------------------------------------------------------
28// Fields
29// ----------------------------------------------------------------------------
30
34template <typename t>
35SEQAN3_CONCEPT fields_specialisation = is_value_specialisation_of_v<t, fields>;
36
37// ----------------------------------------------------------------------------
38// select_types_with_ids
39// ----------------------------------------------------------------------------
40
61template <typename field_types,
62 typename field_types_as_ids,
63 typename selected_field_ids,
64 size_t field_no = 0,
65 typename ...return_types>
66struct select_types_with_ids // unconstrained template is recursion anchor
67{
69 using type = type_list<return_types...>;
70};
71
75template <typename field_types,
76 typename field_types_as_ids,
77 typename selected_field_ids,
78 size_t field_no = 0,
79 typename ...return_types>
80using select_types_with_ids_t = typename select_types_with_ids<field_types,
81 field_types_as_ids,
82 selected_field_ids,
83 field_no,
84 return_types...>::type;
86template <typename field_types,
87 typename field_types_as_ids,
88 typename selected_field_ids,
89 size_t field_no,
90 typename ...return_types>
91 requires (field_no < selected_field_ids::as_array.size()) // perform recursion while not at end
92struct select_types_with_ids<field_types, field_types_as_ids, selected_field_ids, field_no, return_types...>
93{
94 static_assert(field_types_as_ids::contains(selected_field_ids::as_array[field_no]),
95 "You selected a field that was not in field_types_as_ids.");
96
97 // call this type trait again, but increase index by one and append a type to the returned type list.
98 using type = select_types_with_ids_t<field_types,
99 field_types_as_ids,
100 selected_field_ids,
101 field_no + 1,
102 return_types ...,
103 list_traits::at<field_types_as_ids::index_of(
104 selected_field_ids::as_array[field_no]), field_types>>;
105
106};
108
109
110// ----------------------------------------------------------------------------
111// get_or_ignore
112// ----------------------------------------------------------------------------
113
116template <field f, typename field_types, typename field_ids>
117auto & get_or_ignore(record<field_types, field_ids> & r)
118{
119 if constexpr (field_ids::contains(f))
120 return std::get<field_ids::index_of(f)>(r);
121 else
122 return std::ignore;
123}
124
126template <field f, typename field_types, typename field_ids>
127auto const & get_or_ignore(record<field_types, field_ids> const & r)
128{
129 if constexpr (field_ids::contains(f))
130 return std::get<field_ids::index_of(f)>(r);
131 else
132 return std::ignore;
133}
134
136template <size_t i, tuple_like tuple_t>
137auto & get_or_ignore(tuple_t & t)
138{
139 if constexpr (i < std::tuple_size_v<tuple_t>)
140 return std::get<i>(t);
141 else
142 return std::ignore;
143}
144
146template <size_t i, tuple_like tuple_t>
147auto const & get_or_ignore(tuple_t const & t)
148{
149 if constexpr (i < std::tuple_size_v<tuple_t>)
150 return std::get<i>(t);
151 else
152 return std::ignore;
153}
154
155// ----------------------------------------------------------------------------
156// get_or
157// ----------------------------------------------------------------------------
158
161template <field f, typename field_types, typename field_ids, typename or_type>
162decltype(auto) get_or(record<field_types, field_ids> & r, or_type && or_value)
163{
164 if constexpr (field_ids::contains(f))
165 return std::get<field_ids::index_of(f)>(r);
166 else
167 return std::forward<or_type>(or_value);
168}
169
171template <field f, typename field_types, typename field_ids, typename or_type>
172decltype(auto) get_or(record<field_types, field_ids> const & r, or_type && or_value)
173{
174 if constexpr (field_ids::contains(f))
175 return std::get<field_ids::index_of(f)>(r);
176 else
177 return std::forward<or_type>(or_value);
178}
179
181template <size_t i, typename or_type, typename ...types>
182decltype(auto) get_or(std::tuple<types...> & t, or_type && or_value)
183{
184 if constexpr (i < sizeof...(types))
185 return std::get<i>(t);
186 else
187 return std::forward<or_type>(or_value);
188}
189
191template <size_t i, typename or_type, typename ...types>
192decltype(auto) get_or(std::tuple<types...> const & t, or_type && or_value)
193{
194 if constexpr (i < sizeof...(types))
195 return std::get<i>(t);
196 else
197 return std::forward<or_type>(or_value);
198}
199
200// ----------------------------------------------------------------------------
201// range_wrap_ignore
202// ----------------------------------------------------------------------------
203
206template <std::ranges::input_range rng_t>
207inline auto & range_wrap_ignore(rng_t & range)
208{
209 return range;
210}
211
219inline auto range_wrap_ignore(ignore_t const &)
220{
221 return views::repeat(std::ignore);
222}
223
224} // 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 detail::repeat_fn repeat
A view factory that repeats a given value infinitely.
Definition: repeat.hpp:347
constexpr auto const & get(configuration< configs_t... > const &config) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: configuration.hpp:429
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.