SeqAn3 3.1.0
The Modern C++ library for sequence analysis.
pod_tuple.hpp
Go to the documentation of this file.
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
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
28template <typename ...types>
30{};
32
53template <typename type0, typename ...types>
54struct pod_tuple<type0, types...>
55{
56 static_assert(std::is_standard_layout_v<type0> && std::is_trivial_v<type0>, SEQAN_NOT_POD);
59 type0 _head;
61 pod_tuple<types...> _tail;
63
69 constexpr bool operator==(pod_tuple const & rhs) const noexcept
70 {
71 return std::tie(_head, _tail) == std::tie(rhs._head, rhs._tail);
72 }
73
75 constexpr bool operator!=(pod_tuple const & rhs) const noexcept
76 {
77 return std::tie(_head, _tail) != std::tie(rhs._head, rhs._tail);
78 }
79
81 constexpr bool operator<(pod_tuple const & rhs) const noexcept
82 {
83 return std::tie(_head, _tail) < std::tie(rhs._head, rhs._tail);
84 }
85
87 constexpr bool operator>(pod_tuple const & rhs) const noexcept
88 {
89 return std::tie(_head, _tail) > std::tie(rhs._head, rhs._tail);
90 }
91
93 constexpr bool operator<=(pod_tuple const & rhs) const noexcept
94 {
95 return std::tie(_head, _tail) <= std::tie(rhs._head, rhs._tail);
96 }
97
99 constexpr bool operator>=(pod_tuple const & rhs) const noexcept
100 {
101 return std::tie(_head, _tail) >= std::tie(rhs._head, rhs._tail);
102 }
104};
105
110template <typename type0>
111struct pod_tuple<type0>
112{
113 static_assert(std::is_standard_layout_v<type0> && std::is_trivial_v<type0>, SEQAN_NOT_POD);
116 type0 _head;
118
125 constexpr bool operator==(pod_tuple const & rhs) const noexcept
126 {
127 return _head == rhs._head;
128 }
129
131 constexpr bool operator!=(pod_tuple const & rhs) const noexcept
132 {
133 return _head != rhs._head;
134 }
135
137 constexpr bool operator<(pod_tuple const & rhs) const noexcept
138 {
139 return _head < rhs._head;
140 }
141
143 constexpr bool operator>(pod_tuple const & rhs) const noexcept
144 {
145 return _head > rhs._head;
146 }
147
149 constexpr bool operator<=(pod_tuple const & rhs) const noexcept
150 {
151 return _head <= rhs._head;
152 }
153
155 constexpr bool operator>=(pod_tuple const & rhs) const noexcept
156 {
157 return _head >= rhs._head;
158 }
160};
161
162#undef SEQAN_NOT_POD
163
166template <typename ...types>
167pod_tuple(types && ...) -> pod_tuple<types...>;
168
177template <std::size_t i, typename ...types>
178constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
180 requires (i < sizeof...(types))
182{
183 if constexpr (i == 0)
184 return t._head;
185 else
186 return seqan3::get<i-1>(t._tail);
187}
188
191template <std::size_t i, typename ...types>
192constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
194 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
209 requires (i < sizeof...(types))
211{
212 if constexpr (i == 0)
213 return std::move(t._head);
214 else
215 return seqan3::get<i-1>(std::move(t._tail));
216}
217
220template <std::size_t i, typename ...types>
221constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
223 requires (i < sizeof...(types))
225{
226 if constexpr (i == 0)
227 return std::move(t._head);
228 else
229 return seqan3::get<i-1>(std::move(t._tail));
230}
232
243template <typename type, typename ...arg_types>
244constexpr auto & get(seqan3::pod_tuple<arg_types...> & t) noexcept
246 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
248{
249 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(t);
250}
251
254template <typename type, typename ...arg_types>
255constexpr auto const & get(seqan3::pod_tuple<arg_types...> const & t) noexcept
257 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
259{
260 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(t);
261}
262
265template <typename type, typename ...arg_types>
266constexpr auto && get(seqan3::pod_tuple<arg_types...> && t) noexcept
268 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}
273
276template <typename type, typename ...arg_types>
277constexpr auto const && get(seqan3::pod_tuple<arg_types...> const && t) noexcept
279 requires (seqan3::pack_traits::count<type, arg_types...> == 1)
281{
282 return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(std::move(t));
283}
285
286} // namespace seqan3
287
288namespace std
289{
290
292template <std::size_t i, typename ...types>
293constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
294 requires (i < sizeof...(types))
295{
296 return seqan3::get<i>(t);
297}
298
299template <std::size_t i, typename ...types>
300constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
301 requires (i < sizeof...(types))
302{
303 return seqan3::get<i>(t);
304}
305
306template <std::size_t i, typename ...types>
307constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
308 requires (i < sizeof...(types))
309{
310 return seqan3::get<i>(std::move(t));
311}
312
313template <std::size_t i, typename ...types>
314constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
315 requires (i < sizeof...(types))
316{
317 return seqan3::get<i>(std::move(t));
318}
319
320template <typename type, typename ...types>
321constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
322 requires (seqan3::pack_traits::count<type, types...> == 1)
323{
324 return seqan3::get<type>(t);
325}
326
327template <typename type, typename ...types>
328constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
329 requires (seqan3::pack_traits::count<type, types...> == 1)
330{
331 return seqan3::get<type>(t);
332}
333
334template <typename type, typename ...types>
335constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
336 requires (seqan3::pack_traits::count<type, types...> == 1)
337{
338 return seqan3::get<type>(std::move(t));
339}
340
341template <typename type, typename ...types>
342constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
343 requires (seqan3::pack_traits::count<type, types...> == 1)
344{
345 return seqan3::get<type>(std::move(t));
346}
348
354template <std::size_t i, template <typename ...> typename t, typename ...types>
356 requires (i < sizeof...(types)) &&
357 std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
359struct tuple_element<i, t<types...>>
360{
362 using type = seqan3::pack_traits::at<i, types...>;
363};
364
370template <template <typename ...> typename t, typename ...types>
371 requires std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
372struct tuple_size<t<types...>> :
373 public std::integral_constant<std::size_t, sizeof...(types)>
374{};
375
376} // namespace std
constexpr ptrdiff_t find
Get the index of the first occurrence of a type in a pack.
Definition: traits.hpp:187
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: traits.hpp:169
typename decltype(detail::at< idx, pack_t... >())::type at
Return the type at given index from the type pack.
Definition: traits.hpp:256
T is_base_of_v
The main SeqAn3 namespace.
Definition: cigar_operation_table.hpp:2
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
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:99
constexpr bool operator!=(pod_tuple const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition: pod_tuple.hpp:75
constexpr bool operator<=(pod_tuple const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition: pod_tuple.hpp:93
constexpr bool operator==(pod_tuple const &rhs) const noexcept
Checks whether *this is equal to rhs.
Definition: pod_tuple.hpp:69
constexpr bool operator<(pod_tuple const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition: pod_tuple.hpp:81
constexpr bool operator>(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition: pod_tuple.hpp:87
constexpr bool operator<=(pod_tuple const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition: pod_tuple.hpp:149
constexpr bool operator>(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition: pod_tuple.hpp:143
constexpr bool operator>=(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than or equal to rhs.
Definition: pod_tuple.hpp:155
constexpr bool operator!=(pod_tuple const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition: pod_tuple.hpp:131
constexpr bool operator==(pod_tuple const &rhs) const noexcept
Checks whether *this is equal to rhs.
Definition: pod_tuple.hpp:125
constexpr bool operator<(pod_tuple const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition: pod_tuple.hpp:137
cond
Definition: pod_tuple.hpp:30
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:244
constexpr auto const & get(seqan3::pod_tuple< types... > const &t) noexcept
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:192
constexpr auto & get(seqan3::pod_tuple< types... > &t) noexcept
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:178
constexpr auto const && get(seqan3::pod_tuple< types... > const &&t) noexcept
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:221
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:277
constexpr auto && get(seqan3::pod_tuple< arg_types... > &&t) noexcept
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:266
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:255
seqan3::pack_traits::at< i, types... > type
Element type.
Definition: pod_tuple.hpp:362
T tie(T... args)
Provides various traits for template packs.