SeqAn3  3.0.0
The Modern C++ library for sequence analysis.
pod_tuple.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2019, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2019, 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 <meta/meta.hpp>
19 
20 #include <seqan3/core/platform.hpp>
21 
22 namespace seqan3
23 {
24 
26 #define SEQAN_NOT_POD "If you are not going to insert a POD type, use std::tuple instead."
27 
30 template <typename ...types>
31 struct pod_tuple
32 {};
34 
55 template <typename type0, typename ...types>
56 struct pod_tuple<type0, types...>
57 {
58  static_assert(std::is_pod_v<type0>, SEQAN_NOT_POD);
61  type0 _head;
63  pod_tuple<types...> _tail;
65 
70  constexpr bool operator==(pod_tuple const & rhs) const noexcept
72  {
73  return std::tie(_head, _tail) == std::tie(rhs._head, rhs._tail);
74  }
75 
77  constexpr bool operator!=(pod_tuple const & rhs) const noexcept
78  {
79  return std::tie(_head, _tail) != std::tie(rhs._head, rhs._tail);
80  }
81 
83  constexpr bool operator<(pod_tuple const & rhs) const noexcept
84  {
85  return std::tie(_head, _tail) < std::tie(rhs._head, rhs._tail);
86  }
87 
89  constexpr bool operator>(pod_tuple const & rhs) const noexcept
90  {
91  return std::tie(_head, _tail) > std::tie(rhs._head, rhs._tail);
92  }
93 
95  constexpr bool operator<=(pod_tuple const & rhs) const noexcept
96  {
97  return std::tie(_head, _tail) <= std::tie(rhs._head, rhs._tail);
98  }
99 
101  constexpr bool operator>=(pod_tuple const & rhs) const noexcept
102  {
103  return std::tie(_head, _tail) >= std::tie(rhs._head, rhs._tail);
104  }
106 };
107 
112 template <typename type0>
113 struct pod_tuple<type0>
114 {
115  static_assert(std::is_pod_v<type0>, SEQAN_NOT_POD);
118  type0 _head;
120 
126  constexpr bool operator==(pod_tuple const & rhs) const noexcept
128  {
129  return _head == rhs._head;
130  }
131 
133  constexpr bool operator!=(pod_tuple const & rhs) const noexcept
134  {
135  return _head != rhs._head;
136  }
137 
139  constexpr bool operator<(pod_tuple const & rhs) const noexcept
140  {
141  return _head < rhs._head;
142  }
143 
145  constexpr bool operator>(pod_tuple const & rhs) const noexcept
146  {
147  return _head > rhs._head;
148  }
149 
151  constexpr bool operator<=(pod_tuple const & rhs) const noexcept
152  {
153  return _head <= rhs._head;
154  }
155 
157  constexpr bool operator>=(pod_tuple const & rhs) const noexcept
158  {
159  return _head >= rhs._head;
160  }
162 };
163 
164 #undef SEQAN_NOT_POD
165 
168 template <typename ...types>
169 pod_tuple(types && ...) -> pod_tuple<types...>;
170 
177 template <std::size_t i, typename ...types>
179 constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
180  requires i < sizeof...(types)
181 {
182  if constexpr (i == 0)
183  return t._head;
184  else
185  return seqan3::get<i-1>(t._tail);
186 }
187 
189 template <std::size_t i, typename ...types>
190 constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
191  requires i < sizeof...(types)
192 {
193  if constexpr (i == 0)
194  return t._head;
195  else
196  return seqan3::get<i-1>(t._tail);
197 }
198 
199 // extra overloads for temporaries required, because members of temporaries may only be returned as temporaries
201 template <std::size_t i, typename ...types>
202 constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
203  requires i < sizeof...(types)
204 {
205  if constexpr (i == 0)
206  return std::move(t._head);
207  else
208  return seqan3::get<i-1>(std::move(t._tail));
209 }
210 
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 
232 template <typename type, typename ...types>
234 constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
235  requires meta::in<meta::list<types...>, type>::value &&
236  (meta::find_index<meta::list<types...>, type>::value ==
237  meta::reverse_find_index<meta::list<types...>, type>::value)
238 {
239  return seqan3::get<meta::find_index<meta::list<types...>, type>::value>(t);
240 }
241 
243 template <typename type, typename ...types>
244 constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
245  requires meta::in<meta::list<types...>, type>::value &&
246  (meta::find_index<meta::list<types...>, type>::value ==
247  meta::reverse_find_index<meta::list<types...>, type>::value)
248 {
249  return seqan3::get<meta::find_index<meta::list<types...>, type>::value>(t);
250 }
251 
253 template <typename type, typename ...types>
254 constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
255  requires meta::in<meta::list<types...>, type>::value &&
256  (meta::find_index<meta::list<types...>, type>::value ==
257  meta::reverse_find_index<meta::list<types...>, type>::value)
258 {
259  return seqan3::get<meta::find_index<meta::list<types...>, type>::value>(std::move(t));
260 }
261 
263 template <typename type, typename ...types>
264 constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
265  requires meta::in<meta::list<types...>, type>::value &&
266  (meta::find_index<meta::list<types...>, type>::value ==
267  meta::reverse_find_index<meta::list<types...>, type>::value)
268 {
269  return seqan3::get<meta::find_index<meta::list<types...>, type>::value>(std::move(t));
270 }
272 
273 } // namespace seqan3
274 
275 namespace std
276 {
277 
279 template <std::size_t i, typename ...types>
280 constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
281  requires i < sizeof...(types)
282 {
283  return seqan3::get<i>(t);
284 }
285 
286 template <std::size_t i, typename ...types>
287 constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
288  requires i < sizeof...(types)
289 {
290  return seqan3::get<i>(t);
291 }
292 
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>(std::move(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>(std::move(t));
305 }
306 
307 template <typename type, typename ...types>
308 constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
309  requires meta::in<meta::list<types...>, type>::value &&
310  (meta::find_index<meta::list<types...>, type>::value ==
311  meta::reverse_find_index<meta::list<types...>, type>::value)
312 {
313  return seqan3::get<type>(t);
314 }
315 
316 template <typename type, typename ...types>
317 constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
318  requires meta::in<meta::list<types...>, type>::value &&
319  (meta::find_index<meta::list<types...>, type>::value ==
320  meta::reverse_find_index<meta::list<types...>, type>::value)
321 {
322  return seqan3::get<type>(t);
323 }
324 
325 template <typename type, typename ...types>
326 constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
327  requires meta::in<meta::list<types...>, type>::value &&
328  (meta::find_index<meta::list<types...>, type>::value ==
329  meta::reverse_find_index<meta::list<types...>, type>::value)
330 {
331  return seqan3::get<type>(std::move(t));
332 }
333 
334 template <typename type, typename ...types>
335 constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
336  requires meta::in<meta::list<types...>, type>::value &&
337  (meta::find_index<meta::list<types...>, type>::value ==
338  meta::reverse_find_index<meta::list<types...>, type>::value)
339 {
340  return seqan3::get<type>(std::move(t));
341 }
343 
349 template <std::size_t i, template <typename...> typename t, typename ...types >
350  requires i < sizeof...(types) &&
352 struct tuple_element<i, t<types...>>
353 {
354  using type = meta::at_c<meta::list<types...>, i>;
355 };
356 
362 template <template <typename...> typename t, typename ...types >
363  requires std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
364 struct tuple_size<t<types...>> :
365  public std::integral_constant<std::size_t, sizeof...(types)>
366 {};
367 
368 } // namespace std
constexpr bool operator>(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition: pod_tuple.hpp:145
Provides platform and dependency checks.
T tie(T... args)
constexpr bool operator<(pod_tuple const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition: pod_tuple.hpp:83
constexpr bool operator<(pod_tuple const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition: pod_tuple.hpp:139
constexpr bool operator>(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition: pod_tuple.hpp:89
constexpr bool operator>=(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than or equal to rhs.
Definition: pod_tuple.hpp:101
SeqAn specific customisations in the standard namespace.
constexpr auto const & get(configuration< configs_t... > const &config) noexcept
Definition: configuration.hpp:578
The main SeqAn3 namespace.
constexpr bool operator<=(pod_tuple const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition: pod_tuple.hpp:95
T is_base_of_v
constexpr bool operator!=(pod_tuple const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition: pod_tuple.hpp:77
constexpr bool operator!=(pod_tuple const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition: pod_tuple.hpp:133
cond
Definition: pod_tuple.hpp:31
constexpr bool operator<=(pod_tuple const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition: pod_tuple.hpp:151
constexpr bool operator>=(pod_tuple const &rhs) const noexcept
Checks whether *this is greater than or equal to rhs.
Definition: pod_tuple.hpp:157