SeqAn3  3.0.2
The Modern C++ library for sequence analysis.
pod_tuple.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, 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 
18 #include <seqan3/core/platform.hpp>
20 
21 namespace seqan3
22 {
23 
25 #define SEQAN_NOT_POD "If you are not going to insert a POD type, use std::tuple instead."
26 
29 template <typename ...types>
30 struct pod_tuple
31 {};
33 
54 template <typename type0, typename ...types>
55 struct pod_tuple<type0, types...>
56 {
57  static_assert(std::is_standard_layout_v<type0> && std::is_trivial_v<type0>, SEQAN_NOT_POD);
60  type0 _head;
62  pod_tuple<types...> _tail;
64 
69  constexpr bool operator==(pod_tuple const & rhs) const noexcept
71  {
72  return std::tie(_head, _tail) == std::tie(rhs._head, rhs._tail);
73  }
74 
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  }
105 };
106 
111 template <typename type0>
112 struct pod_tuple<type0>
113 {
114  static_assert(std::is_standard_layout_v<type0> && std::is_trivial_v<type0>, SEQAN_NOT_POD);
117  type0 _head;
119 
125  constexpr bool operator==(pod_tuple const & rhs) const noexcept
127  {
128  return _head == rhs._head;
129  }
130 
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  }
161 };
162 
163 #undef SEQAN_NOT_POD
164 
167 template <typename ...types>
168 pod_tuple(types && ...) -> pod_tuple<types...>;
169 
176 template <std::size_t i, typename ...types>
179 constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
181  requires (i < sizeof...(types))
183 {
184  if constexpr (i == 0)
185  return t._head;
186  else
187  return seqan3::get<i-1>(t._tail);
188 }
189 
192 template <std::size_t i, typename ...types>
193 constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
195  requires (i < sizeof...(types))
197 {
198  if constexpr (i == 0)
199  return t._head;
200  else
201  return seqan3::get<i-1>(t._tail);
202 }
203 
204 // extra overloads for temporaries required, because members of temporaries may only be returned as temporaries
207 template <std::size_t i, typename ...types>
208 constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
210  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 
221 template <std::size_t i, typename ...types>
222 constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
224  requires (i < sizeof...(types))
226 {
227  if constexpr (i == 0)
228  return std::move(t._head);
229  else
230  return seqan3::get<i-1>(std::move(t._tail));
231 }
233 
242 template <typename type, typename ...arg_types>
245 constexpr auto & get(seqan3::pod_tuple<arg_types...> & t) noexcept
247  requires (seqan3::pack_traits::count<type, arg_types...> == 1)
249 {
250  return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(t);
251 }
252 
255 template <typename type, typename ...arg_types>
256 constexpr auto const & get(seqan3::pod_tuple<arg_types...> const & t) noexcept
258  requires (seqan3::pack_traits::count<type, arg_types...> == 1)
260 {
261  return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(t);
262 }
263 
266 template <typename type, typename ...arg_types>
267 constexpr auto && get(seqan3::pod_tuple<arg_types...> && t) noexcept
269  requires (seqan3::pack_traits::count<type, arg_types...> == 1)
271 {
272  return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(std::move(t));
273 }
274 
277 template <typename type, typename ...arg_types>
278 constexpr auto const && get(seqan3::pod_tuple<arg_types...> const && t) noexcept
280  requires (seqan3::pack_traits::count<type, arg_types...> == 1)
282 {
283  return seqan3::get<seqan3::pack_traits::find<type, arg_types...>>(std::move(t));
284 }
286 
287 } // namespace seqan3
288 
289 namespace std
290 {
291 
293 template <std::size_t i, typename ...types>
294 constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
295  requires (i < sizeof...(types))
296 {
297  return seqan3::get<i>(t);
298 }
299 
300 template <std::size_t i, typename ...types>
301 constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
302  requires (i < sizeof...(types))
303 {
304  return seqan3::get<i>(t);
305 }
306 
307 template <std::size_t i, typename ...types>
308 constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
309  requires (i < sizeof...(types))
310 {
311  return seqan3::get<i>(std::move(t));
312 }
313 
314 template <std::size_t i, typename ...types>
315 constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
316  requires (i < sizeof...(types))
317 {
318  return seqan3::get<i>(std::move(t));
319 }
320 
321 template <typename type, typename ...types>
322 constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
323  requires (seqan3::pack_traits::count<type, types...> == 1)
324 {
325  return seqan3::get<type>(t);
326 }
327 
328 template <typename type, typename ...types>
329 constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
330  requires (seqan3::pack_traits::count<type, types...> == 1)
331 {
332  return seqan3::get<type>(t);
333 }
334 
335 template <typename type, typename ...types>
336 constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
337  requires (seqan3::pack_traits::count<type, types...> == 1)
338 {
339  return seqan3::get<type>(std::move(t));
340 }
341 
342 template <typename type, typename ...types>
343 constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
344  requires (seqan3::pack_traits::count<type, types...> == 1)
345 {
346  return seqan3::get<type>(std::move(t));
347 }
349 
355 template <std::size_t i, template <typename ...> typename t, typename ...types>
357  requires (i < sizeof...(types)) &&
358  std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
360 struct tuple_element<i, t<types...>>
361 {
363  using type = seqan3::pack_traits::at<i, types...>;
364 };
365 
371 template <template <typename ...> typename t, typename ...types>
372  requires std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
373 struct tuple_size<t<types...>> :
374  public std::integral_constant<std::size_t, sizeof...(types)>
375 {};
376 
377 } // namespace std
seqan3::pod_tuple< type0, types... >::operator!=
constexpr bool operator!=(pod_tuple const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition: pod_tuple.hpp:76
seqan3::pod_tuple::get
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:256
std::integral_constant
seqan3::pod_tuple< type0, types... >::operator<
constexpr bool operator<(pod_tuple const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition: pod_tuple.hpp:82
seqan3::pod_tuple< type0, types... >::operator>
constexpr bool operator>(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition: pod_tuple.hpp:88
seqan3::pod_tuple::get
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:278
seqan3::pod_tuple< type0 >::operator!=
constexpr bool operator!=(pod_tuple const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition: pod_tuple.hpp:132
seqan3::pack_traits::find
constexpr ptrdiff_t find
Get the index of the first occurrence of a type in a pack.
Definition: traits.hpp:152
seqan3::get
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:627
tuple
seqan3::views::get
auto const get
A view calling std::get on each element in a range.
Definition: get.hpp:65
seqan3::pod_tuple< type0, types... >::operator>=
constexpr bool operator>=(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than or equal to rhs.
Definition: pod_tuple.hpp:100
seqan3::pod_tuple< type0 >::operator>
constexpr bool operator>(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition: pod_tuple.hpp:144
seqan3::pod_tuple::pod_tuple
pod_tuple(types &&...) -> pod_tuple< types... >
User defined deduction guide enables easy use.
seqan3::pod_tuple::get
constexpr auto const & get(seqan3::pod_tuple< types... > const &t) noexcept
The same as std::get on an std::tuple.
Definition: pod_tuple.hpp:193
std::tuple_element< i, t< types... > >::type
seqan3::pack_traits::at< i, types... > type
Element type.
Definition: pod_tuple.hpp:363
std::tie
T tie(T... args)
seqan3::pod_tuple::get
constexpr auto const && get(seqan3::pod_tuple< types... > const &&t) noexcept
The same as std::get on an std::tuple.
Definition: pod_tuple.hpp:222
seqan3::pod_tuple< type0 >::operator<=
constexpr bool operator<=(pod_tuple const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition: pod_tuple.hpp:150
seqan3::pod_tuple::get
constexpr auto && get(seqan3::pod_tuple< types... > &&t) noexcept
The same as std::get on an std::tuple.
Definition: pod_tuple.hpp:208
seqan3::pod_tuple< type0 >::operator>=
constexpr bool operator>=(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than or equal to rhs.
Definition: pod_tuple.hpp:156
seqan3::pod_tuple::get
constexpr auto & get(seqan3::pod_tuple< arg_types... > &t) noexcept
The same as std::get on an std::tuple.
Definition: pod_tuple.hpp:245
seqan3::views::move
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:68
seqan3::pod_tuple< type0 >::operator<
constexpr bool operator<(pod_tuple const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition: pod_tuple.hpp:138
seqan3
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
seqan3::pod_tuple::get
constexpr auto && get(seqan3::pod_tuple< arg_types... > &&t) noexcept
The same as std::get on an std::tuple.
Definition: pod_tuple.hpp:267
seqan3::pod_tuple::get
constexpr auto & get(seqan3::pod_tuple< types... > &t) noexcept
The same as std::get on an std::tuple.
Definition: pod_tuple.hpp:179
platform.hpp
Provides platform and dependency checks.
std
SeqAn specific customisations in the standard namespace.
std::size_t
traits.hpp
Provides traits for seqan3::type_list.
seqan3::pack_traits::at
typename decltype(detail::at< idx, pack_t... >())::type at
Return the type at given index from the type pack.
Definition: traits.hpp:221
seqan3::pod_tuple< type0, types... >::operator<=
constexpr bool operator<=(pod_tuple const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition: pod_tuple.hpp:94
seqan3::pod_tuple
cond
Definition: pod_tuple.hpp:31
std::is_base_of_v
T is_base_of_v