SeqAn3
pod_tuple.hpp
Go to the documentation of this file.
1 // ============================================================================
2 // SeqAn - The Library for Sequence Analysis
3 // ============================================================================
4 //
5 // Copyright (c) 2006-2018, Knut Reinert & Freie Universitaet Berlin
6 // Copyright (c) 2016-2018, Knut Reinert & MPI Molekulare Genetik
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // * Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // * Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in the
16 // documentation and/or other materials provided with the distribution.
17 // * Neither the name of Knut Reinert or the FU Berlin nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
25 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 // DAMAGE.
32 //
33 // ============================================================================
34 
40 #pragma once
41 
42 #include <tuple>
43 #include <type_traits>
44 
45 #include <meta/meta.hpp>
46 
47 #include <seqan3/core/platform.hpp>
48 
49 namespace seqan3
50 {
51 
53 #define SEQAN_NOT_POD "If you are not going to insert a POD type, use std::tuple instead."
54 
57 template <typename ...types>
58 struct pod_tuple
59 {};
61 
82 template <typename type0, typename ...types>
83 struct pod_tuple<type0, types...>
84 {
85  static_assert(std::is_pod_v<type0>, SEQAN_NOT_POD);
88  type0 _head;
90  pod_tuple<types...> _tail;
92 
96  constexpr bool operator==(pod_tuple const & rhs) const noexcept
97  {
98  return std::tie(_head, _tail) == std::tie(rhs._head, rhs._tail);
99  }
100 
101  constexpr bool operator!=(pod_tuple const & rhs) const noexcept
102  {
103  return std::tie(_head, _tail) != std::tie(rhs._head, rhs._tail);
104  }
105 
106  constexpr bool operator<(pod_tuple const & rhs) const noexcept
107  {
108  return std::tie(_head, _tail) < std::tie(rhs._head, rhs._tail);
109  }
110 
111  constexpr bool operator>(pod_tuple const & rhs) const noexcept
112  {
113  return std::tie(_head, _tail) > std::tie(rhs._head, rhs._tail);
114  }
115 
116  constexpr bool operator<=(pod_tuple const & rhs) const noexcept
117  {
118  return std::tie(_head, _tail) <= std::tie(rhs._head, rhs._tail);
119  }
120 
121  constexpr bool operator>=(pod_tuple const & rhs) const noexcept
122  {
123  return std::tie(_head, _tail) >= std::tie(rhs._head, rhs._tail);
124  }
126 };
127 
132 template <typename type0>
133 struct pod_tuple<type0>
134 {
135  static_assert(std::is_pod_v<type0>, SEQAN_NOT_POD);
138  type0 _head;
140 
144  constexpr bool operator==(pod_tuple const & rhs) const noexcept
145  {
146  return _head == rhs._head;
147  }
148 
149  constexpr bool operator!=(pod_tuple const & rhs) const noexcept
150  {
151  return _head != rhs._head;
152  }
153 
154  constexpr bool operator<(pod_tuple const & rhs) const noexcept
155  {
156  return _head < rhs._head;
157  }
158 
159  constexpr bool operator>(pod_tuple const & rhs) const noexcept
160  {
161  return _head > rhs._head;
162  }
163 
164  constexpr bool operator<=(pod_tuple const & rhs) const noexcept
165  {
166  return _head <= rhs._head;
167  }
168 
169  constexpr bool operator>=(pod_tuple const & rhs) const noexcept
170  {
171  return _head >= rhs._head;
172  }
174 };
175 
176 #undef SEQAN_NOT_POD
177 
180 template <typename ...types>
181 pod_tuple(types && ...) -> pod_tuple<types...>;
182 
189 template <std::size_t i, typename ...types>
191 constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
192  requires i < sizeof...(types)
193 {
194  if constexpr (i == 0)
195  return t._head;
196  else
197  return seqan3::get<i-1>(t._tail);
198 }
199 
201 template <std::size_t i, typename ...types>
202 constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
203  requires i < sizeof...(types)
204 {
205  if constexpr (i == 0)
206  return t._head;
207  else
208  return seqan3::get<i-1>(t._tail);
209 }
210 
211 // extra overloads for temporaries required, because members of temporaries may only be returned as temporaries
213 template <std::size_t i, typename ...types>
214 constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
215  requires i < sizeof...(types)
216 {
217  if constexpr (i == 0)
218  return std::move(t._head);
219  else
220  return seqan3::get<i-1>(std::move(t._tail));
221 }
222 
224 template <std::size_t i, typename ...types>
225 constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
226  requires i < sizeof...(types)
227 {
228  if constexpr (i == 0)
229  return std::move(t._head);
230  else
231  return seqan3::get<i-1>(std::move(t._tail));
232 }
234 
244 template <typename type, typename ...types>
246 constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
247  requires meta::in<meta::list<types...>, type>::value &&
248  (meta::find_index<meta::list<types...>, type>::value ==
249  meta::reverse_find_index<meta::list<types...>, type>::value)
250 {
251  return seqan3::get<meta::find_index<meta::list<types...>, type>::value>(t);
252 }
253 
255 template <typename type, typename ...types>
256 constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
257  requires meta::in<meta::list<types...>, type>::value &&
258  (meta::find_index<meta::list<types...>, type>::value ==
259  meta::reverse_find_index<meta::list<types...>, type>::value)
260 {
261  return seqan3::get<meta::find_index<meta::list<types...>, type>::value>(t);
262 }
263 
265 template <typename type, typename ...types>
266 constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
267  requires meta::in<meta::list<types...>, type>::value &&
268  (meta::find_index<meta::list<types...>, type>::value ==
269  meta::reverse_find_index<meta::list<types...>, type>::value)
270 {
271  return seqan3::get<meta::find_index<meta::list<types...>, type>::value>(std::move(t));
272 }
273 
275 template <typename type, typename ...types>
276 constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
277  requires meta::in<meta::list<types...>, type>::value &&
278  (meta::find_index<meta::list<types...>, type>::value ==
279  meta::reverse_find_index<meta::list<types...>, type>::value)
280 {
281  return seqan3::get<meta::find_index<meta::list<types...>, type>::value>(std::move(t));
282 }
284 
285 } // namespace seqan3
286 
287 namespace std
288 {
289 
291 template <std::size_t i, typename ...types>
292 constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
293  requires i < sizeof...(types)
294 {
295  return seqan3::get<i>(t);
296 }
297 
298 template <std::size_t i, typename ...types>
299 constexpr auto const & get(seqan3::pod_tuple<types...> const & t) noexcept
300  requires i < sizeof...(types)
301 {
302  return seqan3::get<i>(t);
303 }
304 
305 template <std::size_t i, typename ...types>
306 constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
307  requires i < sizeof...(types)
308 {
309  return seqan3::get<i>(std::move(t));
310 }
311 
312 template <std::size_t i, typename ...types>
313 constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
314  requires i < sizeof...(types)
315 {
316  return seqan3::get<i>(std::move(t));
317 }
318 
319 template <typename type, typename ...types>
320 constexpr auto & get(seqan3::pod_tuple<types...> & t) noexcept
321  requires meta::in<meta::list<types...>, type>::value &&
322  (meta::find_index<meta::list<types...>, type>::value ==
323  meta::reverse_find_index<meta::list<types...>, type>::value)
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 meta::in<meta::list<types...>, type>::value &&
331  (meta::find_index<meta::list<types...>, type>::value ==
332  meta::reverse_find_index<meta::list<types...>, type>::value)
333 {
334  return seqan3::get<type>(t);
335 }
336 
337 template <typename type, typename ...types>
338 constexpr auto && get(seqan3::pod_tuple<types...> && t) noexcept
339  requires meta::in<meta::list<types...>, type>::value &&
340  (meta::find_index<meta::list<types...>, type>::value ==
341  meta::reverse_find_index<meta::list<types...>, type>::value)
342 {
343  return seqan3::get<type>(std::move(t));
344 }
345 
346 template <typename type, typename ...types>
347 constexpr auto const && get(seqan3::pod_tuple<types...> const && t) noexcept
348  requires meta::in<meta::list<types...>, type>::value &&
349  (meta::find_index<meta::list<types...>, type>::value ==
350  meta::reverse_find_index<meta::list<types...>, type>::value)
351 {
352  return seqan3::get<type>(std::move(t));
353 }
355 
358 template <std::size_t i, template <typename...> typename t, typename ...types >
359  requires i < sizeof...(types) &&
360  std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
361 struct tuple_element<i, t<types...>>
362 {
363  using type = meta::at_c<meta::list<types...>, i>;
364 };
365 
368 template <template <typename...> typename t, typename ...types >
369  requires std::is_base_of_v<seqan3::pod_tuple<types...>, t<types...>>
370 struct tuple_size<t<types...>> :
371  public std::integral_constant<std::size_t, sizeof...(types)>
372 {};
373 
374 } // namespace std
Contains platform and dependency checks.
SeqAn specific customisations in the standard namespace.
Definition: align_result.hpp:221
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:58
constexpr auto const & get(detail::configuration< cfg_elements_t... > const &cfg) noexcept
Definition: utility.hpp:364
pod_tuple(types &&...) -> pod_tuple< types... >
User defined deduction guide enables easy use.
Provides C++20 additions to the type_traits header.
cond
Definition: pod_tuple.hpp:58