SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
pod_tuple.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <tuple>
13#include <type_traits>
14
16
17namespace seqan3
18{
19
21#define SEQAN_NOT_POD "If you are not going to insert a POD type, use std::tuple instead."
23
24template <typename... types>
26{};
27
46template <typename type0, typename... types>
47struct pod_tuple<type0, types...>
48{
49 static_assert(std::is_standard_layout_v<type0> && std::is_trivial_v<type0>, SEQAN_NOT_POD);
52 type0 _head;
54 pod_tuple<types...> _tail;
55
56 constexpr pod_tuple() noexcept = default;
57 constexpr pod_tuple(pod_tuple const &) noexcept = default;
58 constexpr pod_tuple & operator=(pod_tuple const &) noexcept = default;
59 constexpr pod_tuple(pod_tuple &&) noexcept = default;
60 constexpr pod_tuple & operator=(pod_tuple &&) noexcept = default;
61 constexpr ~pod_tuple() noexcept = default;
62
64 constexpr pod_tuple(type0 v0, types... args) noexcept : _head{v0}, _tail{args...}
65 {}
67
73 constexpr bool operator==(pod_tuple const & rhs) const noexcept
74 {
75 return std::tie(_head, _tail) == std::tie(rhs._head, rhs._tail);
76 }
77
79 constexpr bool operator!=(pod_tuple const & rhs) const noexcept
80 {
81 return std::tie(_head, _tail) != std::tie(rhs._head, rhs._tail);
82 }
83
85 constexpr bool operator<(pod_tuple const & rhs) const noexcept
86 {
87 return std::tie(_head, _tail) < std::tie(rhs._head, rhs._tail);
88 }
89
91 constexpr bool operator>(pod_tuple const & rhs) const noexcept
92 {
93 return std::tie(_head, _tail) > std::tie(rhs._head, rhs._tail);
94 }
95
97 constexpr bool operator<=(pod_tuple const & rhs) const noexcept
98 {
99 return std::tie(_head, _tail) <= std::tie(rhs._head, rhs._tail);
100 }
101
103 constexpr bool operator>=(pod_tuple const & rhs) const noexcept
104 {
105 return std::tie(_head, _tail) >= std::tie(rhs._head, rhs._tail);
106 }
108};
109
114template <typename type0>
115struct pod_tuple<type0>
116{
117 static_assert(std::is_standard_layout_v<type0> && std::is_trivial_v<type0>, SEQAN_NOT_POD);
120 type0 _head;
122
129 constexpr bool operator==(pod_tuple const & rhs) const noexcept
130 {
131 return _head == rhs._head;
132 }
133
135 constexpr bool operator!=(pod_tuple const & rhs) const noexcept
136 {
137 return _head != rhs._head;
138 }
139
141 constexpr bool operator<(pod_tuple const & rhs) const noexcept
142 {
143 return _head < rhs._head;
144 }
145
147 constexpr bool operator>(pod_tuple const & rhs) const noexcept
148 {
149 return _head > rhs._head;
150 }
151
153 constexpr bool operator<=(pod_tuple const & rhs) const noexcept
154 {
155 return _head <= rhs._head;
156 }
157
159 constexpr bool operator>=(pod_tuple const & rhs) const noexcept
160 {
161 return _head >= rhs._head;
162 }
164};
165
166#undef SEQAN_NOT_POD
167
170template <typename... types>
171pod_tuple(types &&...) -> pod_tuple<types...>;
172
181template <std::size_t i, typename... types>
182constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
183 requires (i < sizeof...(types))
184{
185 if constexpr (i == 0)
186 return t._head;
187 else
188 return seqan3::get<i - 1>(t._tail);
189}
190
193template <std::size_t i, typename... types>
194constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
195 requires (i < sizeof...(types))
196{
197 if constexpr (i == 0)
198 return t._head;
199 else
200 return seqan3::get<i - 1>(t._tail);
201}
202
203// extra overloads for temporaries required, because members of temporaries may only be returned as temporaries
206template <std::size_t i, typename... types>
207constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
208 requires (i < sizeof...(types))
209{
210 if constexpr (i == 0)
211 return std::move(t._head);
212 else
213 return seqan3::get<i - 1>(std::move(t._tail));
214}
215
218template <std::size_t i, typename... types>
219constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
220 requires (i < sizeof...(types))
221{
222 if constexpr (i == 0)
223 return std::move(t._head);
224 else
225 return seqan3::get<i - 1>(std::move(t._tail));
226}
228
239template <typename type, typename... arg_types>
240constexpr auto & get(seqan3::pod_tuple<arg_types...> & t) noexcept
241 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
242{
243 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(t);
244}
245
248template <typename type, typename... arg_types>
249constexpr auto const & get(seqan3::pod_tuple<arg_types...> const & t) noexcept
250 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
251{
252 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(t);
253}
254
257template <typename type, typename... arg_types>
258constexpr auto && get(seqan3::pod_tuple<arg_types...> && t) noexcept
259 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
260{
261 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(std::move(t));
262}
263
266template <typename type, typename... arg_types>
267constexpr auto const && get(seqan3::pod_tuple<arg_types...> const && t) noexcept
268 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
269{
270 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(std::move(t));
271}
273
274} // namespace seqan3
275
276namespace std
277{
278
280template <std::size_t i, typename... types>
281constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
282 requires (i < sizeof...(types))
283{
284 return seqan3::get<i>(t);
285}
286
287template <std::size_t i, typename... types>
288constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
289 requires (i < sizeof...(types))
290{
291 return seqan3::get<i>(t);
292}
293
294template <std::size_t i, typename... types>
295constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
296 requires (i < sizeof...(types))
297{
298 return seqan3::get<i>(std::move(t));
299}
300
301template <std::size_t i, typename... types>
302constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
303 requires (i < sizeof...(types))
304{
305 return seqan3::get<i>(std::move(t));
306}
307
308template <typename type, typename... types>
309constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
310 requires (seqan3::pack_traits::count<type, types...> == 1)
311{
312 return seqan3::get<type>(t);
313}
314
315template <typename type, typename... types>
316constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
317 requires (seqan3::pack_traits::count<type, types...> == 1)
318{
319 return seqan3::get<type>(t);
320}
321
322template <typename type, typename... types>
323constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
324 requires (seqan3::pack_traits::count<type, types...> == 1)
325{
326 return seqan3::get<type>(std::move(t));
327}
328
329template <typename type, typename... types>
330constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
331 requires (seqan3::pack_traits::count<type, types...> == 1)
332{
333 return seqan3::get<type>(std::move(t));
334}
336
342template <std::size_t i, template <typename...> typename t, typename... types>
343 requires (i < sizeof...(types)) && std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
344struct tuple_element<i, t<types...>>
345{
347 using type = seqan3::pack_traits::at<i, types...>;
348};
349
355template <template <typename...> typename t, typename... types>
356 requires std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
357struct tuple_size<t<types...>> : public std::integral_constant<std::size_t, sizeof...(types)>
358{};
359
360} // namespace std
constexpr ptrdiff_t find
Get the index of the first occurrence of a type in a pack.
Definition type_pack/traits.hpp:179
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition type_pack/traits.hpp:161
typename decltype(detail::at< idx, pack_t... >())::type at
Return the type at given index from the type pack.
Definition type_pack/traits.hpp:245
Subconcept definition for seqan3::tuple_like to test for std::tuple_size-interface.
T is_base_of_v
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
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:412
SeqAn specific customisations in the standard namespace.
constexpr bool operator>=(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than or equal to rhs.
Definition pod_tuple.hpp:103
type0 _head
The first element as member.
Definition pod_tuple.hpp:52
constexpr bool operator!=(pod_tuple const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition pod_tuple.hpp:79
constexpr bool operator<=(pod_tuple const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition pod_tuple.hpp:97
constexpr pod_tuple() noexcept=default
Defaulted.
constexpr bool operator==(pod_tuple const &rhs) const noexcept
Checks whether *this is equal to rhs.
Definition pod_tuple.hpp:73
pod_tuple< types... > _tail
The rest of the elements defined as a "recursive member".
Definition pod_tuple.hpp:54
constexpr bool operator<(pod_tuple const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition pod_tuple.hpp:85
constexpr bool operator>(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition pod_tuple.hpp:91
constexpr bool operator<=(pod_tuple const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition pod_tuple.hpp:153
constexpr bool operator>(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition pod_tuple.hpp:147
constexpr bool operator>=(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than or equal to rhs.
Definition pod_tuple.hpp:159
constexpr bool operator!=(pod_tuple const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition pod_tuple.hpp:135
type0 _head
The first element as member.
Definition pod_tuple.hpp:120
constexpr bool operator==(pod_tuple const &rhs) const noexcept
Checks whether *this is equal to rhs.
Definition pod_tuple.hpp:129
constexpr bool operator<(pod_tuple const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition pod_tuple.hpp:141
Definition pod_tuple.hpp:26
constexpr auto && get(seqan3::pod_tuple< types... > &&t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:207
constexpr auto & get(seqan3::pod_tuple< arg_types... > &t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:240
constexpr auto const & get(seqan3::pod_tuple< types... > const &t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:194
constexpr auto & get(seqan3::pod_tuple< types... > &t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:182
constexpr auto const && get(seqan3::pod_tuple< types... > const &&t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:219
constexpr auto const && get(seqan3::pod_tuple< arg_types... > const &&t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:267
constexpr auto && get(seqan3::pod_tuple< arg_types... > &&t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:258
pod_tuple(types &&...) -> pod_tuple< types... >
User defined deduction guide enables easy use.
constexpr auto const & get(seqan3::pod_tuple< arg_types... > const &t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:249
seqan3::pack_traits::at< i, types... > type
Element type.
Definition pod_tuple.hpp:347
T tie(T... args)
Provides various traits for template packs.
Hide me