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// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2023, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2023, 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
13#pragma once
14
15#include <tuple>
16#include <type_traits>
17
19
20namespace seqan3
21{
22
24#define SEQAN_NOT_POD "If you are not going to insert a POD type, use std::tuple instead."
26
27template <typename... types>
29{};
30
49template <typename type0, typename... types>
50struct pod_tuple<type0, types...>
51{
52 static_assert(std::is_standard_layout_v<type0> && std::is_trivial_v<type0>, SEQAN_NOT_POD);
55 type0 _head;
57 pod_tuple<types...> _tail;
58
59 constexpr pod_tuple() noexcept = default;
60 constexpr pod_tuple(pod_tuple const &) noexcept = default;
61 constexpr pod_tuple & operator=(pod_tuple const &) noexcept = default;
62 constexpr pod_tuple(pod_tuple &&) noexcept = default;
63 constexpr pod_tuple & operator=(pod_tuple &&) noexcept = default;
64 constexpr ~pod_tuple() noexcept = default;
65
67 constexpr pod_tuple(type0 v0, types... args) noexcept : _head{v0}, _tail{args...}
68 {}
70
76 constexpr bool operator==(pod_tuple const & rhs) const noexcept
77 {
78 return std::tie(_head, _tail) == std::tie(rhs._head, rhs._tail);
79 }
80
82 constexpr bool operator!=(pod_tuple const & rhs) const noexcept
83 {
84 return std::tie(_head, _tail) != std::tie(rhs._head, rhs._tail);
85 }
86
88 constexpr bool operator<(pod_tuple const & rhs) const noexcept
89 {
90 return std::tie(_head, _tail) < std::tie(rhs._head, rhs._tail);
91 }
92
94 constexpr bool operator>(pod_tuple const & rhs) const noexcept
95 {
96 return std::tie(_head, _tail) > std::tie(rhs._head, rhs._tail);
97 }
98
100 constexpr bool operator<=(pod_tuple const & rhs) const noexcept
101 {
102 return std::tie(_head, _tail) <= std::tie(rhs._head, rhs._tail);
103 }
104
106 constexpr bool operator>=(pod_tuple const & rhs) const noexcept
107 {
108 return std::tie(_head, _tail) >= std::tie(rhs._head, rhs._tail);
109 }
111};
112
117template <typename type0>
118struct pod_tuple<type0>
119{
120 static_assert(std::is_standard_layout_v<type0> && std::is_trivial_v<type0>, SEQAN_NOT_POD);
123 type0 _head;
125
132 constexpr bool operator==(pod_tuple const & rhs) const noexcept
133 {
134 return _head == rhs._head;
135 }
136
138 constexpr bool operator!=(pod_tuple const & rhs) const noexcept
139 {
140 return _head != rhs._head;
141 }
142
144 constexpr bool operator<(pod_tuple const & rhs) const noexcept
145 {
146 return _head < rhs._head;
147 }
148
150 constexpr bool operator>(pod_tuple const & rhs) const noexcept
151 {
152 return _head > rhs._head;
153 }
154
156 constexpr bool operator<=(pod_tuple const & rhs) const noexcept
157 {
158 return _head <= rhs._head;
159 }
160
162 constexpr bool operator>=(pod_tuple const & rhs) const noexcept
163 {
164 return _head >= rhs._head;
165 }
167};
168
169#undef SEQAN_NOT_POD
170
173template <typename... types>
174pod_tuple(types &&...) -> pod_tuple<types...>;
175
184template <std::size_t i, typename... types>
185constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
186 requires (i < sizeof...(types))
187{
188 if constexpr (i == 0)
189 return t._head;
190 else
191 return seqan3::get<i - 1>(t._tail);
192}
193
196template <std::size_t i, typename... types>
197constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
198 requires (i < sizeof...(types))
199{
200 if constexpr (i == 0)
201 return t._head;
202 else
203 return seqan3::get<i - 1>(t._tail);
204}
205
206// extra overloads for temporaries required, because members of temporaries may only be returned as temporaries
209template <std::size_t i, typename... types>
210constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
211 requires (i < sizeof...(types))
212{
213 if constexpr (i == 0)
214 return std::move(t._head);
215 else
216 return seqan3::get<i - 1>(std::move(t._tail));
217}
218
221template <std::size_t i, typename... types>
222constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
223 requires (i < sizeof...(types))
224{
225 if constexpr (i == 0)
226 return std::move(t._head);
227 else
228 return seqan3::get<i - 1>(std::move(t._tail));
229}
231
242template <typename type, typename... arg_types>
243constexpr auto & get(seqan3::pod_tuple<arg_types...> & t) noexcept
244 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
245{
246 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(t);
247}
248
251template <typename type, typename... arg_types>
252constexpr auto const & get(seqan3::pod_tuple<arg_types...> const & t) noexcept
253 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
254{
255 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(t);
256}
257
260template <typename type, typename... arg_types>
261constexpr auto && get(seqan3::pod_tuple<arg_types...> && t) noexcept
262 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
263{
264 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(std::move(t));
265}
266
269template <typename type, typename... arg_types>
270constexpr auto const && get(seqan3::pod_tuple<arg_types...> const && t) noexcept
271 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
272{
273 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(std::move(t));
274}
276
277} // namespace seqan3
278
279namespace std
280{
281
283template <std::size_t i, typename... types>
284constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
285 requires (i < sizeof...(types))
286{
287 return seqan3::get<i>(t);
288}
289
290template <std::size_t i, typename... types>
291constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
292 requires (i < sizeof...(types))
293{
294 return seqan3::get<i>(t);
295}
296
297template <std::size_t i, typename... types>
298constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
299 requires (i < sizeof...(types))
300{
301 return seqan3::get<i>(std::move(t));
302}
303
304template <std::size_t i, typename... types>
305constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
306 requires (i < sizeof...(types))
307{
308 return seqan3::get<i>(std::move(t));
309}
310
311template <typename type, typename... types>
312constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
313 requires (seqan3::pack_traits::count<type, types...> == 1)
314{
315 return seqan3::get<type>(t);
316}
317
318template <typename type, typename... types>
319constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
320 requires (seqan3::pack_traits::count<type, types...> == 1)
321{
322 return seqan3::get<type>(t);
323}
324
325template <typename type, typename... types>
326constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
327 requires (seqan3::pack_traits::count<type, types...> == 1)
328{
329 return seqan3::get<type>(std::move(t));
330}
331
332template <typename type, typename... types>
333constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
334 requires (seqan3::pack_traits::count<type, types...> == 1)
335{
336 return seqan3::get<type>(std::move(t));
337}
339
345template <std::size_t i, template <typename...> typename t, typename... types>
346 requires (i < sizeof...(types)) && std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
347struct tuple_element<i, t<types...>>
348{
350 using type = seqan3::pack_traits::at<i, types...>;
351};
352
358template <template <typename...> typename t, typename... types>
359 requires std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
360struct tuple_size<t<types...>> : public std::integral_constant<std::size_t, sizeof...(types)>
361{};
362
363} // namespace std
constexpr ptrdiff_t find
Get the index of the first occurrence of a type in a pack.
Definition type_pack/traits.hpp:182
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition type_pack/traits.hpp:164
typename decltype(detail::at< idx, pack_t... >())::type at
Return the type at given index from the type pack.
Definition type_pack/traits.hpp:248
T is_base_of_v
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:29
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:415
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:106
constexpr bool operator!=(pod_tuple const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition pod_tuple.hpp:82
constexpr bool operator<=(pod_tuple const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition pod_tuple.hpp:100
constexpr bool operator==(pod_tuple const &rhs) const noexcept
Checks whether *this is equal to rhs.
Definition pod_tuple.hpp:76
constexpr bool operator<(pod_tuple const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition pod_tuple.hpp:88
constexpr bool operator>(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition pod_tuple.hpp:94
constexpr bool operator<=(pod_tuple const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition pod_tuple.hpp:156
constexpr bool operator>(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition pod_tuple.hpp:150
constexpr bool operator>=(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than or equal to rhs.
Definition pod_tuple.hpp:162
constexpr bool operator!=(pod_tuple const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition pod_tuple.hpp:138
constexpr bool operator==(pod_tuple const &rhs) const noexcept
Checks whether *this is equal to rhs.
Definition pod_tuple.hpp:132
constexpr bool operator<(pod_tuple const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition pod_tuple.hpp:144
Definition pod_tuple.hpp:29
constexpr auto && get(seqan3::pod_tuple< types... > &&t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:210
constexpr auto & get(seqan3::pod_tuple< arg_types... > &t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:243
constexpr auto const & get(seqan3::pod_tuple< types... > const &t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:197
constexpr auto & get(seqan3::pod_tuple< types... > &t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:185
constexpr auto const && get(seqan3::pod_tuple< types... > const &&t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:222
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:270
constexpr auto && get(seqan3::pod_tuple< arg_types... > &&t) noexcept
The same as std::get on a std::tuple.
Definition pod_tuple.hpp:261
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:252
seqan3::pack_traits::at< i, types... > type
Element type.
Definition pod_tuple.hpp:350
T tie(T... args)
Provides various traits for template packs.