SeqAn3 3.2.0
The Modern C++ library for sequence analysis.
pod_tuple.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, 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
51template <typename type0, typename... types>
52struct pod_tuple<type0, types...>
53{
54 static_assert(std::is_standard_layout_v<type0> && std::is_trivial_v<type0>, SEQAN_NOT_POD);
57 type0 _head;
59 pod_tuple<types...> _tail;
61
67 constexpr bool operator==(pod_tuple const & rhs) const noexcept
68 {
69 return std::tie(_head, _tail) == std::tie(rhs._head, rhs._tail);
70 }
71
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 }
102};
103
108template <typename type0>
109struct pod_tuple<type0>
110{
111 static_assert(std::is_standard_layout_v<type0> && std::is_trivial_v<type0>, SEQAN_NOT_POD);
114 type0 _head;
116
123 constexpr bool operator==(pod_tuple const & rhs) const noexcept
124 {
125 return _head == rhs._head;
126 }
127
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 }
158};
159
160#undef SEQAN_NOT_POD
161
164template <typename... types>
165pod_tuple(types &&...) -> pod_tuple<types...>;
166
175template <std::size_t i, typename... types>
176constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
177 requires (i < sizeof...(types))
178{
179 if constexpr (i == 0)
180 return t._head;
181 else
182 return seqan3::get<i - 1>(t._tail);
183}
184
187template <std::size_t i, typename... types>
188constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
189 requires (i < sizeof...(types))
190{
191 if constexpr (i == 0)
192 return t._head;
193 else
194 return seqan3::get<i - 1>(t._tail);
195}
196
197// extra overloads for temporaries required, because members of temporaries may only be returned as temporaries
200template <std::size_t i, typename... types>
201constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
202 requires (i < sizeof...(types))
203{
204 if constexpr (i == 0)
205 return std::move(t._head);
206 else
207 return seqan3::get<i - 1>(std::move(t._tail));
208}
209
212template <std::size_t i, typename... types>
213constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
214 requires (i < sizeof...(types))
215{
216 if constexpr (i == 0)
217 return std::move(t._head);
218 else
219 return seqan3::get<i - 1>(std::move(t._tail));
220}
222
233template <typename type, typename... arg_types>
234constexpr auto & get(seqan3::pod_tuple<arg_types...> & t) noexcept
235 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
236{
237 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(t);
238}
239
242template <typename type, typename... arg_types>
243constexpr auto const & get(seqan3::pod_tuple<arg_types...> const & 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 && get(seqan3::pod_tuple<arg_types...> && t) noexcept
253 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
254{
255 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(std::move(t));
256}
257
260template <typename type, typename... arg_types>
261constexpr auto const && get(seqan3::pod_tuple<arg_types...> const && 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}
267
268} // namespace seqan3
269
270namespace std
271{
272
274template <std::size_t i, typename... types>
275constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
276 requires (i < sizeof...(types))
277{
278 return seqan3::get<i>(t);
279}
280
281template <std::size_t i, typename... types>
282constexpr auto const & get(seqan3::pod_tuple<types...> const & 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 && get(seqan3::pod_tuple<types...> && t) noexcept
290 requires (i < sizeof...(types))
291{
292 return seqan3::get<i>(std::move(t));
293}
294
295template <std::size_t i, typename... types>
296constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
297 requires (i < sizeof...(types))
298{
299 return seqan3::get<i>(std::move(t));
300}
301
302template <typename type, typename... types>
303constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
304 requires (seqan3::pack_traits::count<type, types...> == 1)
305{
306 return seqan3::get<type>(t);
307}
308
309template <typename type, typename... types>
310constexpr auto const & get(seqan3::pod_tuple<types...> const & 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 && get(seqan3::pod_tuple<types...> && t) noexcept
318 requires (seqan3::pack_traits::count<type, types...> == 1)
319{
320 return seqan3::get<type>(std::move(t));
321}
322
323template <typename type, typename... types>
324constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
325 requires (seqan3::pack_traits::count<type, types...> == 1)
326{
327 return seqan3::get<type>(std::move(t));
328}
330
336template <std::size_t i, template <typename...> typename t, typename... types>
337 requires (i < sizeof...(types)) && std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
338struct tuple_element<i, t<types...>>
339{
341 using type = seqan3::pack_traits::at<i, types...>;
342};
343
349template <template <typename...> typename t, typename... types>
350 requires std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
351struct tuple_size<t<types...>> : public std::integral_constant<std::size_t, sizeof...(types)>
352{};
353
354} // namespace std
constexpr ptrdiff_t find
Get the index of the first occurrence of a type in a pack.
Definition: traits.hpp:182
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: traits.hpp:164
typename decltype(detail::at< idx, pack_t... >())::type at
Return the type at given index from the type pack.
Definition: 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:97
constexpr bool operator!=(pod_tuple const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition: pod_tuple.hpp:73
constexpr bool operator<=(pod_tuple const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition: pod_tuple.hpp:91
constexpr bool operator==(pod_tuple const &rhs) const noexcept
Checks whether *this is equal to rhs.
Definition: pod_tuple.hpp:67
constexpr bool operator<(pod_tuple const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition: pod_tuple.hpp:79
constexpr bool operator>(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition: pod_tuple.hpp:85
constexpr bool operator<=(pod_tuple const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition: pod_tuple.hpp:147
constexpr bool operator>(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition: pod_tuple.hpp:141
constexpr bool operator>=(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than or equal to rhs.
Definition: pod_tuple.hpp:153
constexpr bool operator!=(pod_tuple const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition: pod_tuple.hpp:129
constexpr bool operator==(pod_tuple const &rhs) const noexcept
Checks whether *this is equal to rhs.
Definition: pod_tuple.hpp:123
constexpr bool operator<(pod_tuple const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition: pod_tuple.hpp:135
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:201
constexpr auto & get(seqan3::pod_tuple< arg_types... > &t) noexcept
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:234
constexpr auto const & get(seqan3::pod_tuple< types... > const &t) noexcept
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:188
constexpr auto & get(seqan3::pod_tuple< types... > &t) noexcept
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:176
constexpr auto const && get(seqan3::pod_tuple< types... > const &&t) noexcept
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:213
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:261
constexpr auto && get(seqan3::pod_tuple< arg_types... > &&t) noexcept
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:252
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:243
seqan3::pack_traits::at< i, types... > type
Element type.
Definition: pod_tuple.hpp:341
T tie(T... args)
Provides various traits for template packs.