SeqAn3  3.2.0
The Modern C++ library for sequence analysis.
utility/tuple/concept.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2022, 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 <concepts>
16 #include <tuple>
17 #include <type_traits>
18 
23 
24 namespace seqan3::detail
25 {
26 
33 template <typename tuple_t>
34 concept tuple_size = requires (tuple_t v) {
35  {
36  std::tuple_size<tuple_t>::value
37  } -> std::convertible_to<size_t>;
38  };
40 
47 template <typename tuple_t>
48 concept tuple_get =
49  requires (tuple_t & v, tuple_t const & v_c) {
50  requires std::tuple_size_v<tuple_t> > 0;
51 
52  typename std::tuple_element<0, tuple_t>::type;
53 
54  {
55  get<0>(v)
56  } -> std::convertible_to<typename std::tuple_element<0, tuple_t>::type>;
57  // requires weakly_assignable_from<decltype(get<0>(v)), typename std::tuple_element<0, tuple_t>::type>;
58  //TODO check that the previous returns something that can be assigned to
59  // unfortunately std::assignable_from requires lvalue-reference, but we want to accept xvalues too (returned
60  // proxies)
61  {
62  get<0>(v_c)
63  } -> std::convertible_to<typename std::tuple_element<0, tuple_t>::type>;
64  {
65  get<0>(std::move(v))
66  } -> std::convertible_to<typename std::tuple_element<0, tuple_t>::type>;
67  {
68  get<0>(std::move(v_c))
69  } -> std::convertible_to<typename std::tuple_element<0, tuple_t>::type const &&>;
70  };
72 
80 template <detail::tuple_size tuple_t>
81 struct tuple_type_list
82 {
83 protected:
85  template <size_t... Is>
86  static constexpr auto invoke_to_type_list(std::index_sequence<Is...>)
87  {
88  return type_list<std::tuple_element_t<Is, tuple_t>...>{};
89  }
90 
91 public:
93  using type = decltype(invoke_to_type_list(std::make_index_sequence<std::tuple_size<tuple_t>::value>{}));
94 };
95 
101 template <detail::tuple_size tuple_t>
102 using tuple_type_list_t = typename tuple_type_list<tuple_t>::type;
103 
107 template <typename... elements_t>
108 inline constexpr auto all_elements_model_totally_ordered(seqan3::type_list<elements_t...>)
109  -> std::bool_constant<(std::totally_ordered<elements_t> && ... && true)>;
110 
115 template <typename tuple_t>
116  requires requires () {
117  {
118  detail::all_elements_model_totally_ordered(tuple_type_list_t<tuple_t>{})
119  };
120  }
121 static constexpr bool all_elements_model_totally_ordered_v =
122  decltype(detail::all_elements_model_totally_ordered(tuple_type_list_t<tuple_t>{}))::value;
123 } // namespace seqan3::detail
124 
125 namespace seqan3
126 {
127 
128 // ----------------------------------------------------------------------------
129 // tuple_like
130 // ----------------------------------------------------------------------------
131 
181 template <typename t>
182 concept tuple_like =
183  detail::tuple_size<std::remove_reference_t<t>>
184  && requires (t v) {
185  typename detail::tuple_type_list<std::remove_cvref_t<t>>::type;
186 
187  // NOTE(rrahn): To check the full tuple_concept including the get interface and the std::totally_ordered
188  // we need to make some assumptions. In general these checks can only be executed if the tuple is not
189  // empty. Furthermore, the std::totally_ordered can only be checked if all elements in the
190  // tuple are strict_totally_ordered. This is done, by the fold expression in the second part.
191  requires (std::tuple_size<std::remove_reference_t<t>>::value == 0)
192  || (detail::tuple_get<std::remove_cvref_t<t>>
193  && (!detail::all_elements_model_totally_ordered_v<std::remove_cvref_t<t>>
194  || std::totally_ordered<std::remove_cvref_t<t>>));
195  };
197 
209 template <typename t>
210 concept pair_like = tuple_like<t> && std::tuple_size_v<std::remove_reference_t<t>> == 2;
212 
213 } // namespace seqan3
Provides various type traits on generic types.
The <concepts> header from C++20's standard library.
requires requires
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition: alphabet/concept.hpp:164
Whether a type behaves like a tuple with exactly two elements.
Whether a type behaves like a tuple.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
Provides seqan3::pod_tuple.
Type that contains multiple types.
Definition: type_list.hpp:29
Provides type traits for working with templates.
Provides seqan3::type_list.