SeqAn3  3.0.3
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 
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 
28 template <typename ...types>
29 struct pod_tuple
30 {};
32 
53 template <typename type0, typename ...types>
54 struct 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 
110 template <typename type0>
111 struct 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 
166 template <typename ...types>
167 pod_tuple(types && ...) -> pod_tuple<types...>;
168 
177 template <std::size_t i, typename ...types>
178 constexpr 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 
191 template <std::size_t i, typename ...types>
192 constexpr 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
206 template <std::size_t i, typename ...types>
207 constexpr 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 
220 template <std::size_t i, typename ...types>
221 constexpr 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 
243 template <typename type, typename ...arg_types>
244 constexpr 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 
254 template <typename type, typename ...arg_types>
255 constexpr 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 
265 template <typename type, typename ...arg_types>
266 constexpr 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 
276 template <typename type, typename ...arg_types>
277 constexpr 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 
288 namespace std
289 {
290 
292 template <std::size_t i, typename ...types>
293 constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
294  requires (i < sizeof...(types))
295 {
296  return seqan3::get<i>(t);
297 }
298 
299 template <std::size_t i, typename ...types>
300 constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
301  requires (i < sizeof...(types))
302 {
303  return seqan3::get<i>(t);
304 }
305 
306 template <std::size_t i, typename ...types>
307 constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
308  requires (i < sizeof...(types))
309 {
310  return seqan3::get<i>(std::move(t));
311 }
312 
313 template <std::size_t i, typename ...types>
314 constexpr 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 
320 template <typename type, typename ...types>
321 constexpr 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 
327 template <typename type, typename ...types>
328 constexpr 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 
334 template <typename type, typename ...types>
335 constexpr 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 
341 template <typename type, typename ...types>
342 constexpr 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 
354 template <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...>>
359 struct tuple_element<i, t<types...>>
360 {
362  using type = seqan3::pack_traits::at<i, types...>;
363 };
364 
370 template <template <typename ...> typename t, typename ...types>
371  requires std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
372 struct 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
typename decltype(detail::at< idx, pack_t... >())::type at
Return the type at given index from the type pack.
Definition: traits.hpp:256
constexpr auto get
A view calling get on each element in a range.
Definition: elements.hpp:114
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:74
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: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 an std::tuple.
Definition: pod_tuple.hpp:207
constexpr auto & get(seqan3::pod_tuple< arg_types... > &t) noexcept
The same as std::get on an std::tuple.
Definition: pod_tuple.hpp:244
constexpr auto const & get(seqan3::pod_tuple< types... > const &t) noexcept
The same as std::get on an std::tuple.
Definition: pod_tuple.hpp:192
constexpr auto & get(seqan3::pod_tuple< types... > &t) noexcept
The same as std::get on an std::tuple.
Definition: pod_tuple.hpp:178
constexpr auto const && get(seqan3::pod_tuple< types... > const &&t) noexcept
The same as std::get on an 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 an std::tuple.
Definition: pod_tuple.hpp:277
constexpr auto && get(seqan3::pod_tuple< arg_types... > &&t) noexcept
The same as std::get on an 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 an 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.