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 
20 namespace seqan3
21 {
22 
24 #define SEQAN_NOT_POD "If you are not going to insert a POD type, use std::tuple instead."
26 
27 template <typename... types>
28 struct pod_tuple
29 {};
30 
51 template <typename type0, typename... types>
52 struct 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 
108 template <typename type0>
109 struct 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 
164 template <typename... types>
165 pod_tuple(types &&...) -> pod_tuple<types...>;
166 
175 template <std::size_t i, typename... types>
176 constexpr 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 
187 template <std::size_t i, typename... types>
188 constexpr 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
200 template <std::size_t i, typename... types>
201 constexpr 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 
212 template <std::size_t i, typename... types>
213 constexpr 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 
233 template <typename type, typename... arg_types>
234 constexpr 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 
242 template <typename type, typename... arg_types>
243 constexpr 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 
251 template <typename type, typename... arg_types>
252 constexpr 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 
260 template <typename type, typename... arg_types>
261 constexpr 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 
270 namespace std
271 {
272 
274 template <std::size_t i, typename... types>
275 constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
276  requires (i < sizeof...(types))
277 {
278  return seqan3::get<i>(t);
279 }
280 
281 template <std::size_t i, typename... types>
282 constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
283  requires (i < sizeof...(types))
284 {
285  return seqan3::get<i>(t);
286 }
287 
288 template <std::size_t i, typename... types>
289 constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
290  requires (i < sizeof...(types))
291 {
292  return seqan3::get<i>(std::move(t));
293 }
294 
295 template <std::size_t i, typename... types>
296 constexpr 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 
302 template <typename type, typename... types>
303 constexpr 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 
309 template <typename type, typename... types>
310 constexpr 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 
316 template <typename type, typename... types>
317 constexpr 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 
323 template <typename type, typename... types>
324 constexpr 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 
336 template <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...>>
338 struct tuple_element<i, t<types...>>
339 {
341  using type = seqan3::pack_traits::at<i, types...>;
342 };
343 
349 template <template <typename...> typename t, typename... types>
350  requires std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
351 struct tuple_size<t<types...>> : public std::integral_constant<std::size_t, sizeof...(types)>
352 {};
353 
354 } // namespace std
requires requires
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition: alphabet/concept.hpp:164
constexpr ptrdiff_t find
Get the index of the first occurrence of a type in a pack.
Definition: type_pack/traits.hpp:182
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 const && get(seqan3::pod_tuple< types... > const &&t) noexcept requires(i< sizeof...(types))
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:213
constexpr auto const & get(seqan3::pod_tuple< types... > const &t) noexcept requires(i< sizeof...(types))
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:188
constexpr auto const & get(seqan3::pod_tuple< arg_types... > const &t) noexcept requires(seqan3
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:243
constexpr auto const && get(seqan3::pod_tuple< arg_types... > const &&t) noexcept requires(seqan3
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:261
constexpr auto & get(seqan3::pod_tuple< types... > &t) noexcept requires(i< sizeof...(types))
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:176
constexpr auto && get(seqan3::pod_tuple< types... > &&t) noexcept requires(i< sizeof...(types))
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:201
constexpr auto & get(seqan3::pod_tuple< arg_types... > &t) noexcept requires(seqan3
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:234
pod_tuple(types &&...) -> pod_tuple< types... >
User defined deduction guide enables easy use.
constexpr auto && get(seqan3::pod_tuple< arg_types... > &&t) noexcept requires(seqan3
The same as std::get on a std::tuple.
Definition: pod_tuple.hpp:252
T tie(T... args)
Provides various traits for template packs.