SeqAn3
tuple_utility.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 <meta/meta.hpp>
43 
44 #include <utility>
45 
51 
52 namespace seqan3::detail
53 {
54 
68 template <size_t beg,
69  template <typename ...> typename tuple_t,
70  size_t ... Is,
71  typename ...ts>
73  requires tuple_like_concept<tuple_t<ts...>> && tuple_like_concept<tuple_t<>>
75 constexpr auto tuple_split(tuple_t<ts...> const & t, std::index_sequence<Is...> const & SEQAN3_DOXYGEN_ONLY(idx))
76 {
77  return tuple_t<std::tuple_element_t<beg + Is, tuple_t<ts...>>...>{std::get<beg + Is>(t)...};
78 }
79 
81 template <size_t beg,
82  template <typename ...> typename tuple_t,
83  size_t ... Is,
84  typename ...ts>
86  requires tuple_like_concept<tuple_t<ts...>> && tuple_like_concept<tuple_t<>>
88 constexpr auto tuple_split(tuple_t<ts...> && t, std::index_sequence<Is...> const & SEQAN3_DOXYGEN_ONLY(idx))
89 {
90  return tuple_t<std::tuple_element_t<beg + Is, tuple_t<ts...>>...>{std::move(std::get<beg + Is>(t))...};
91 }
92 } // namespace seqan3::detail
93 
94 namespace seqan3
95 {
128 template <size_t pivot_c, template <typename ...> typename tuple_t, typename ... ts>
130  requires tuple_like_concept<tuple_t<ts...>>
132 constexpr auto tuple_split(tuple_t<ts...> const & t)
133 {
134  static_assert(pivot_c <= sizeof...(ts));
135 
136  return tuple_t{detail::tuple_split<0>(t, std::make_index_sequence<pivot_c>{}),
137  detail::tuple_split<pivot_c>(t, std::make_index_sequence<sizeof...(ts) - pivot_c>{})};
138 }
139 
141 template <size_t pivot_c, template <typename ...> typename tuple_t, typename ... ts>
143  requires tuple_like_concept<tuple_t<ts...>>
145 constexpr auto tuple_split(tuple_t<ts...> && t)
146 {
147  static_assert(pivot_c <= sizeof...(ts));
148 
149  return tuple_t{detail::tuple_split<0>(std::move(t), std::make_index_sequence<pivot_c>{}),
150  detail::tuple_split<pivot_c>(std::move(t), std::make_index_sequence<sizeof...(ts) - pivot_c>{})};
151 }
152 
163 template <typename pivot_t, tuple_like_concept tuple_t>
164 constexpr auto tuple_split(tuple_t && t)
165 {
166  constexpr size_t pivot_c = meta::find_index<detail::tuple_type_list_t<remove_cvref_t<tuple_t>>, pivot_t>::value;
167 
168  static_assert(pivot_c <= std::tuple_size_v<remove_cvref_t<tuple_t>>);
169 
170  return tuple_split<pivot_c>(std::forward<tuple_t>(t));
171 }
172 
193 template <tuple_like_concept tuple_t>
194 constexpr auto tuple_pop_front(tuple_t && t)
195 {
196  static_assert(std::tuple_size_v<remove_cvref_t<tuple_t>> > 0);
197 
198  return std::get<1>(tuple_split<1>(std::forward<tuple_t>(t)));
199 }
201 } // namespace seqan3
constexpr auto tuple_split(tuple_t< ts... > const &t)
Splits a tuple like data structure at the given position.
Definition: tuple_utility.hpp:132
Provides seqan3::type_list and auxiliary metafunctions.
Whether a type behaves like a tuple.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:58
Contains seqan3::pod_tuple.
Provides seqan3::type_list and auxiliary metafunctions.
Provides seqan3::tuple_like_concept.
std::remove_cv_t< std::remove_reference_t< t > > remove_cvref_t
Return the input type with const, volatile and references removed [Type metafunction].
Definition: basic.hpp:64
Definition: aligned_sequence_concept.hpp:288
Provides various metafunctions on generic types.
constexpr auto tuple_pop_front(tuple_t &&t)
Removes the first element of a tuple.
Definition: tuple_utility.hpp:194