SeqAn3
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 
49 #include <seqan3/std/concepts>
50 
51 namespace seqan3::detail
52 {
53 
59 template <typename tuple_t>
61 concept tuple_size_concept = requires (tuple_t v)
62 {
63  { std::tuple_size<tuple_t>::value } -> size_t;
64 };
66 
72 template <typename tuple_t>
74 concept tuple_get_concept = requires (tuple_t & v, tuple_t const & v_c)
75 {
76  requires std::tuple_size_v<tuple_t> > 0;
77 
78  typename std::tuple_element<0, tuple_t>::type;
79  { get<0>(v) } -> typename std::tuple_element<0, tuple_t>::type;
80 // requires weakly_assignable_concept<decltype(get<0>(v)), typename std::tuple_element<0, tuple_t>::type>;
81  //TODO check that the previous returns something that can be assigned to
82  // unfortunately std::Assignable requires lvalue-reference, but we want to accept xvalues too (returned proxies)
83  { get<0>(v_c) } -> typename std::tuple_element<0, tuple_t>::type;
84  { get<0>(std::move(v)) } -> typename std::tuple_element<0, tuple_t>::type;
85  // TODO: The return type for std::tuple is wrong until gcc-8.0, for gcc > 8.0 this is fixed.
86  { get<0>(std::move(v_c)) };// -> typename std::tuple_element<0, tuple_t>::type const &&;
87 };
89 
99 template <typename state_t, typename element_t>
100 struct models_strict_totally_ordered
101 {
103  using type = std::conditional_t<state_t::value && std::StrictTotallyOrdered<element_t>,
104  std::true_type,
105  std::false_type>;
106 };
107 
115 template <detail::tuple_size_concept tuple_t>
116 struct tuple_type_list
117 {
118 protected:
119 
121  template <size_t ... Is>
122  static constexpr auto invoke_to_type_list(std::index_sequence<Is...>)
123  {
124  return type_list<std::tuple_element_t<Is, tuple_t>...>{};
125  }
126 
127 public:
129  using type = decltype(invoke_to_type_list(std::make_index_sequence<std::tuple_size<tuple_t>::value>{}));
130 };
131 
137 template <detail::tuple_size_concept tuple_t>
138 using tuple_type_list_t = typename tuple_type_list<tuple_t>::type;
139 } // namespace::seqan3
140 
141 namespace seqan3
142 {
143 
144 // ----------------------------------------------------------------------------
145 // tuple_like_concept
146 // ----------------------------------------------------------------------------
147 
195 template <typename t>
198 concept tuple_like_concept = detail::tuple_size_concept<std::remove_reference_t<t>> && requires(t v)
199 {
200  typename detail::tuple_type_list<remove_cvref_t<t>>::type;
201 
202  // NOTE(rrahn): To check the full tuple_concept including the get interface and the std::StrictTotallyOrdered
203  // we need to make some assumptions. In general these checks can only be executed if the tuple is not
204  // empty. Furthermore, the std::StrictTotallyOrdered can only be checked if all elements in the
205  // tuple are strict_totally_ordered. This is done, by the fold expression in the second part.
206  requires (std::tuple_size<std::remove_reference_t<t>>::value == 0) ||
207  detail::tuple_get_concept<remove_cvref_t<t>> &&
208  (!meta::fold<detail::tuple_type_list_t<remove_cvref_t<t>>,
209  std::true_type,
210  meta::quote_trait<detail::models_strict_totally_ordered>>::value ||
212 };
214 
215 } // namespace seqan3
Provides seqan3::type_list and auxiliary metafunctions.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:58
Contains seqan3::pod_tuple.
Provides seqan3::type_list and auxiliary metafunctions.
The Concepts library.
Definition: aligned_sequence_concept.hpp:288
Provides C++20 additions to the type_traits header.
Provides various metafunctions on generic types.
Requires std::EqualityComparable and all remaing comparison operators (<, <=, >, >=).