SeqAn3 3.1.0
The Modern C++ library for sequence analysis.
concept.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2021, 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 <seqan3/std/concepts>
16#include <tuple>
17#include <type_traits>
18
23
24namespace seqan3::detail
25{
26
33template <typename tuple_t>
34SEQAN3_CONCEPT tuple_size = requires (tuple_t v)
35{
36 SEQAN3_RETURN_TYPE_CONSTRAINT(std::tuple_size<tuple_t>::value, std::convertible_to, size_t);
37};
39
46template <typename tuple_t>
47SEQAN3_CONCEPT tuple_get = 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
53 SEQAN3_RETURN_TYPE_CONSTRAINT(get<0>(v), std::convertible_to, typename std::tuple_element<0, tuple_t>::type);
54// requires weakly_assignable_from<decltype(get<0>(v)), typename std::tuple_element<0, tuple_t>::type>;
55 //TODO check that the previous returns something that can be assigned to
56 // unfortunately std::assignable_from requires lvalue-reference, but we want to accept xvalues too (returned
57 // proxies)
58 SEQAN3_RETURN_TYPE_CONSTRAINT(get<0>(v_c), std::convertible_to, typename std::tuple_element<0, tuple_t>::type);
59 SEQAN3_RETURN_TYPE_CONSTRAINT(get<0>(std::move(v)),
60 std::convertible_to, typename std::tuple_element<0, tuple_t>::type);
61 // TODO: The return type for std::tuple is wrong until gcc-8.0, for gcc > 8.0 this is fixed.
62 { get<0>(std::move(v_c)) };// -> typename std::tuple_element<0, tuple_t>::type const &&;
63 // SEQAN3_RETURN_TYPE_CONSTRAINT(get<0>(std::move(v_c)),
64 // std::convertible_to, typename std::tuple_element<0, tuple_t>::type const &&);
65};
67
75template <detail::tuple_size tuple_t>
76struct tuple_type_list
77{
78protected:
79
81 template <size_t ... Is>
82 static constexpr auto invoke_to_type_list(std::index_sequence<Is...>)
83 {
84 return type_list<std::tuple_element_t<Is, tuple_t>...>{};
85 }
86
87public:
89 using type = decltype(invoke_to_type_list(std::make_index_sequence<std::tuple_size<tuple_t>::value>{}));
90};
91
97template <detail::tuple_size tuple_t>
98using tuple_type_list_t = typename tuple_type_list<tuple_t>::type;
99
103template <typename ...elements_t>
104inline constexpr auto all_elements_model_totally_ordered(seqan3::type_list<elements_t...>)
105 -> std::bool_constant<(std::totally_ordered<elements_t> && ... && true)>;
106
111template <typename tuple_t>
113 requires requires()
114 {
115 { detail::all_elements_model_totally_ordered(tuple_type_list_t<tuple_t>{}) };
116 }
118static constexpr bool all_elements_model_totally_ordered_v =
119 decltype(detail::all_elements_model_totally_ordered(tuple_type_list_t<tuple_t>{}))::value;
120} // namespace seqan3::detail
121
122namespace seqan3
123{
124
125// ----------------------------------------------------------------------------
126// tuple_like
127// ----------------------------------------------------------------------------
128
178template <typename t>
179SEQAN3_CONCEPT tuple_like = detail::tuple_size<std::remove_reference_t<t>> && requires(t v)
180{
181 typename detail::tuple_type_list<std::remove_cvref_t<t>>::type;
182
183 // NOTE(rrahn): To check the full tuple_concept including the get interface and the std::totally_ordered
184 // we need to make some assumptions. In general these checks can only be executed if the tuple is not
185 // empty. Furthermore, the std::totally_ordered can only be checked if all elements in the
186 // tuple are strict_totally_ordered. This is done, by the fold expression in the second part.
187 requires (std::tuple_size<std::remove_reference_t<t>>::value == 0) ||
188 (detail::tuple_get<std::remove_cvref_t<t>> &&
189 (!detail::all_elements_model_totally_ordered_v<std::remove_cvref_t<t>> ||
190 std::totally_ordered<std::remove_cvref_t<t>>));
191};
193
205template <typename t>
206SEQAN3_CONCEPT pair_like = tuple_like<t> && std::tuple_size_v<std::remove_reference_t<t>> == 2;
208
209} // namespace seqan3
Provides various type traits on generic types.
The <concepts> header from C++20's standard library.
Whether a type behaves like a tuple with exactly two elements.
Whether a type behaves like a tuple.
The main SeqAn3 namespace.
Definition: cigar_operation_table.hpp:2
#define SEQAN3_RETURN_TYPE_CONSTRAINT(expression, concept_name,...)
Same as writing {expression} -> concept_name<type1[, ...]> in a concept definition.
Definition: platform.hpp:57
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.