SeqAn3  3.0.0
The Modern C++ library for sequence analysis.
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 
22 #include <seqan3/std/concepts>
23 
24 namespace seqan3::detail
25 {
26 
32 template <typename tuple_t>
34 SEQAN3_CONCEPT TupleSize = requires (tuple_t v)
35 {
36  { std::tuple_size<tuple_t>::value } -> size_t;
37 };
39 
45 template <typename tuple_t>
47 SEQAN3_CONCEPT TupleGet = requires (tuple_t & v, tuple_t const & v_c)
48 {
49  requires std::tuple_size_v<tuple_t> > 0;
50 
51  typename std::tuple_element<0, tuple_t>::type;
52  { get<0>(v) } -> typename std::tuple_element<0, tuple_t>::type;
53 // requires WeaklyAssignable<decltype(get<0>(v)), typename std::tuple_element<0, tuple_t>::type>;
54  //TODO check that the previous returns something that can be assigned to
55  // unfortunately std::Assignable requires lvalue-reference, but we want to accept xvalues too (returned proxies)
56  { get<0>(v_c) } -> typename std::tuple_element<0, tuple_t>::type;
57  { get<0>(std::move(v)) } -> typename std::tuple_element<0, tuple_t>::type;
58  // TODO: The return type for std::tuple is wrong until gcc-8.0, for gcc > 8.0 this is fixed.
59  { get<0>(std::move(v_c)) };// -> typename std::tuple_element<0, tuple_t>::type const &&;
60 };
62 
72 template <typename state_t, typename element_t>
73 struct models_strict_totally_ordered
74 {
79 };
80 
88 template <detail::TupleSize tuple_t>
89 struct tuple_type_list
90 {
91 protected:
92 
94  template <size_t ... Is>
95  static constexpr auto invoke_to_type_list(std::index_sequence<Is...>)
96  {
97  return type_list<std::tuple_element_t<Is, tuple_t>...>{};
98  }
99 
100 public:
102  using type = decltype(invoke_to_type_list(std::make_index_sequence<std::tuple_size<tuple_t>::value>{}));
103 };
104 
110 template <detail::TupleSize tuple_t>
111 using tuple_type_list_t = typename tuple_type_list<tuple_t>::type;
112 } // namespace::seqan3
113 
114 namespace seqan3
115 {
116 
117 // ----------------------------------------------------------------------------
118 // TupleLike
119 // ----------------------------------------------------------------------------
120 
168 template <typename t>
171 SEQAN3_CONCEPT TupleLike = detail::TupleSize<std::remove_reference_t<t>> && requires(t v)
172 {
173  typename detail::tuple_type_list<remove_cvref_t<t>>::type;
174 
175  // NOTE(rrahn): To check the full tuple_concept including the get interface and the std::StrictTotallyOrdered
176  // we need to make some assumptions. In general these checks can only be executed if the tuple is not
177  // empty. Furthermore, the std::StrictTotallyOrdered can only be checked if all elements in the
178  // tuple are strict_totally_ordered. This is done, by the fold expression in the second part.
179  requires (std::tuple_size<std::remove_reference_t<t>>::value == 0) ||
180  detail::TupleGet<remove_cvref_t<t>> &&
181  (!meta::fold<detail::tuple_type_list_t<remove_cvref_t<t>>,
183  meta::quote_trait<detail::models_strict_totally_ordered>>::value ||
185 };
187 
188 } // namespace seqan3
Provides seqan3::type_list and auxiliary type traits.
The main SeqAn3 namespace.
Provides seqan3::pod_tuple.
Provides seqan3::type_list and auxiliary type traits.
The Concepts library.
Definition: aligned_sequence_concept.hpp:35
Provides various type traits on generic types.
Requires std::EqualityComparable and all remaing comparison operators (<, <=, >, >=).