SeqAn3 3.4.0-rc.3
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
17
18namespace seqan3
19{
20
22#define SEQAN_NOT_POD "If you are not going to insert a POD type, use std::tuple instead."
24
25template <typename... types>
27{};
28
47template <typename type0, typename... types>
48struct pod_tuple<type0, types...>
49{
50 static_assert(std::is_standard_layout_v<type0> && seqan3::trivial<type0>, SEQAN_NOT_POD);
53 type0 _head;
55 pod_tuple<types...> _tail;
56
57 constexpr pod_tuple() noexcept = default;
58 constexpr pod_tuple(pod_tuple const &) noexcept = default;
59 constexpr pod_tuple & operator=(pod_tuple const &) noexcept = default;
60 constexpr pod_tuple(pod_tuple &&) noexcept = default;
61 constexpr pod_tuple & operator=(pod_tuple &&) noexcept = default;
62 constexpr ~pod_tuple() noexcept = default;
63
65 constexpr pod_tuple(type0 v0, types... args) noexcept : _head{v0}, _tail{args...}
66 {}
68
74 constexpr bool operator==(pod_tuple const & rhs) const noexcept
75 {
76 return std::tie(_head, _tail) == std::tie(rhs._head, rhs._tail);
77 }
78
80 constexpr bool operator!=(pod_tuple const & rhs) const noexcept
81 {
82 return std::tie(_head, _tail) != std::tie(rhs._head, rhs._tail);
83 }
84
86 constexpr bool operator<(pod_tuple const & rhs) const noexcept
87 {
88 return std::tie(_head, _tail) < std::tie(rhs._head, rhs._tail);
89 }
90
92 constexpr bool operator>(pod_tuple const & rhs) const noexcept
93 {
94 return std::tie(_head, _tail) > std::tie(rhs._head, rhs._tail);
95 }
96
98 constexpr bool operator<=(pod_tuple const & rhs) const noexcept
99 {
100 return std::tie(_head, _tail) <= std::tie(rhs._head, rhs._tail);
101 }
102
104 constexpr bool operator>=(pod_tuple const & rhs) const noexcept
105 {
106 return std::tie(_head, _tail) >= std::tie(rhs._head, rhs._tail);
107 }
109};
110
115template <typename type0>
116struct pod_tuple<type0>
117{
118 static_assert(std::is_standard_layout_v<type0> && seqan3::trivial<type0>, SEQAN_NOT_POD);
121 type0 _head;
123
130 constexpr bool operator==(pod_tuple const & rhs) const noexcept
131 {
132 return _head == rhs._head;
133 }
134
136 constexpr bool operator!=(pod_tuple const & rhs) const noexcept
137 {
138 return _head != rhs._head;
139 }
140
142 constexpr bool operator<(pod_tuple const & rhs) const noexcept
143 {
144 return _head < rhs._head;
145 }
146
148 constexpr bool operator>(pod_tuple const & rhs) const noexcept
149 {
150 return _head > rhs._head;
151 }
152
154 constexpr bool operator<=(pod_tuple const & rhs) const noexcept
155 {
156 return _head <= rhs._head;
157 }
158
160 constexpr bool operator>=(pod_tuple const & rhs) const noexcept
161 {
162 return _head >= rhs._head;
163 }
165};
166
167#undef SEQAN_NOT_POD
168
171template <typename... types>
172pod_tuple(types &&...) -> pod_tuple<types...>;
173
182template <std::size_t i, typename... types>
183constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
184 requires (i < sizeof...(types))
185{
186 if constexpr (i == 0)
187 return t._head;
188 else
189 return seqan3::get<i - 1>(t._tail);
190}
191
194template <std::size_t i, typename... types>
195constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
196 requires (i < sizeof...(types))
197{
198 if constexpr (i == 0)
199 return t._head;
200 else
201 return seqan3::get<i - 1>(t._tail);
202}
203
204// extra overloads for temporaries required, because members of temporaries may only be returned as temporaries
207template <std::size_t i, typename... types>
208constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
209 requires (i < sizeof...(types))
210{
211 if constexpr (i == 0)
212 return std::move(t._head);
213 else
214 return seqan3::get<i - 1>(std::move(t._tail));
215}
216
219template <std::size_t i, typename... types>
220constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
221 requires (i < sizeof...(types))
222{
223 if constexpr (i == 0)
224 return std::move(t._head);
225 else
226 return seqan3::get<i - 1>(std::move(t._tail));
227}
229
240template <typename type, typename... arg_types>
241constexpr auto & get(seqan3::pod_tuple<arg_types...> & t) noexcept
242 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
243{
244 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(t);
245}
246
249template <typename type, typename... arg_types>
250constexpr auto const & get(seqan3::pod_tuple<arg_types...> const & t) noexcept
251 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
252{
253 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(t);
254}
255
258template <typename type, typename... arg_types>
259constexpr auto && get(seqan3::pod_tuple<arg_types...> && t) noexcept
260 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
261{
262 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(std::move(t));
263}
264
267template <typename type, typename... arg_types>
268constexpr auto const && get(seqan3::pod_tuple<arg_types...> const && t) noexcept
269 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
270{
271 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(std::move(t));
272}
274
275} // namespace seqan3
276
277namespace std
278{
279
281template <std::size_t i, typename... types>
282constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
283 requires (i < sizeof...(types))
284{
285 return seqan3::get<i>(t);
286}
287
288template <std::size_t i, typename... types>
289constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
290 requires (i < sizeof...(types))
291{
292 return seqan3::get<i>(t);
293}
294
295template <std::size_t i, typename... types>
296constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
297 requires (i < sizeof...(types))
298{
299 return seqan3::get<i>(std::move(t));
300}
301
302template <std::size_t i, typename... types>
303constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
304 requires (i < sizeof...(types))
305{
306 return seqan3::get<i>(std::move(t));
307}
308
309template <typename type, typename... types>
310constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
311 requires (seqan3::pack_traits::count<type, types...> == 1)
312{
313 return seqan3::get<type>(t);
314}
315
316template <typename type, typename... types>
317constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
318 requires (seqan3::pack_traits::count<type, types...> == 1)
319{
320 return seqan3::get<type>(t);
321}
322
323template <typename type, typename... types>
324constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
325 requires (seqan3::pack_traits::count<type, types...> == 1)
326{
327 return seqan3::get<type>(std::move(t));
328}
329
330template <typename type, typename... types>
331constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
332 requires (seqan3::pack_traits::count<type, types...> == 1)
333{
334 return seqan3::get<type>(std::move(t));
335}
337
343template <std::size_t i, template <typename...> typename t, typename... types>
344 requires (i < sizeof...(types)) && std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
345struct tuple_element<i, t<types...>>
346{
348 using type = seqan3::pack_traits::at<i, types...>;
349};
350
356template <template <typename...> typename t, typename... types>
357 requires std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
358struct tuple_size<t<types...>> : public std::integral_constant<std::size_t, sizeof...(types)>
359{};
360
361} // 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
A type that satisfies seqan3::trivially_copyable and seqan3::trivially_destructible.
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:104
constexpr bool operator!=(pod_tuple const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition pod_tuple.hpp:80
constexpr bool operator<=(pod_tuple const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition pod_tuple.hpp:98
constexpr bool operator==(pod_tuple const &rhs) const noexcept
Checks whether *this is equal to rhs.
Definition pod_tuple.hpp:74
constexpr bool operator<(pod_tuple const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition pod_tuple.hpp:86
constexpr bool operator>(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition pod_tuple.hpp:92
constexpr bool operator<=(pod_tuple const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition pod_tuple.hpp:154
constexpr bool operator>(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition pod_tuple.hpp:148
constexpr bool operator>=(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than or equal to rhs.
Definition pod_tuple.hpp:160
constexpr bool operator!=(pod_tuple const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition pod_tuple.hpp:136
constexpr bool operator==(pod_tuple const &rhs) const noexcept
Checks whether *this is equal to rhs.
Definition pod_tuple.hpp:130
constexpr bool operator<(pod_tuple const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition pod_tuple.hpp:142
Definition pod_tuple.hpp:27
constexpr auto && get(seqan3::pod_tuple< types... > &&t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:208
constexpr auto & get(seqan3::pod_tuple< arg_types... > &t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:241
constexpr auto const & get(seqan3::pod_tuple< types... > const &t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:195
constexpr auto & get(seqan3::pod_tuple< types... > &t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:183
constexpr auto const && get(seqan3::pod_tuple< types... > const &&t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:220
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:268
constexpr auto && get(seqan3::pod_tuple< arg_types... > &&t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:259
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:250
seqan3::pack_traits::at< i, types... > type
Element type.
Definition pod_tuple.hpp:348
T tie(T... args)
Provides various traits for template packs.
Provides concepts that do not have equivalents in C++20.
Hide me