BioC++ core-0.7.0
The Modern C++ libraries for Bioinformatics.
 
Loading...
Searching...
No Matches
tuple.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2022 deCODE Genetics
3// Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
4// Copyright (c) 2016-2021, Knut Reinert & MPI für molekulare Genetik
5// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
6// shipped with this file and also available at: https://github.com/biocpp/biocpp-core/blob/main/LICENSE.md
7// -----------------------------------------------------------------------------------------------------
8
14#pragma once
15
16#include <concepts>
17#include <tuple>
18#include <type_traits>
19
24
25namespace bio::meta::detail
26{
27
32template <typename tuple_t>
33concept tuple_size = requires(tuple_t v) {
34 {
35 std::tuple_size<tuple_t>::value
36 } -> std::convertible_to<size_t>;
37};
38
43template <typename tuple_t>
44concept tuple_get = requires(tuple_t & v, tuple_t const & v_c) {
45 requires std::tuple_size_v<tuple_t> > 0;
46
47 typename std::tuple_element<0, tuple_t>::type;
48
49 {
50 get<0>(v)
51 } -> std::convertible_to<typename std::tuple_element<0, tuple_t>::type>;
52 // requires weakly_assignable_from<decltype(get<0>(v)), typename std::tuple_element<0, tuple_t>::type>;
53 //TODO check that the previous returns something that can be assigned to
54 // unfortunately std::assignable_from requires lvalue-reference, but we want to accept xvalues too (returned
55 // proxies)
56 {
57 get<0>(v_c)
58 } -> std::convertible_to<typename std::tuple_element<0, tuple_t>::type>;
59 {
60 get<0>(std::move(v))
61 } -> std::convertible_to<typename std::tuple_element<0, tuple_t>::type>;
62 {
63 get<0>(std::move(v_c))
64 } -> std::convertible_to<typename std::tuple_element<0, tuple_t>::type const &&>;
65};
66
74template <detail::tuple_size tuple_t>
75struct tuple_type_list
76{
77protected:
79 template <size_t... Is>
80 static constexpr auto invoke_to_type_list(std::index_sequence<Is...>)
81 {
82 return type_list<std::tuple_element_t<Is, tuple_t>...>{};
83 }
84
85public:
87 using type = decltype(invoke_to_type_list(std::make_index_sequence<std::tuple_size<tuple_t>::value>{}));
88};
89
95template <detail::tuple_size tuple_t>
96using tuple_type_list_t = typename tuple_type_list<tuple_t>::type;
97
101template <typename... elements_t>
102inline constexpr auto all_elements_model_totally_ordered(meta::type_list<elements_t...>)
103 -> std::bool_constant<(std::totally_ordered<elements_t> && ... && true)>;
104
109template <typename tuple_t>
110 requires(requires {
111 {
112 detail::all_elements_model_totally_ordered(tuple_type_list_t<tuple_t>{})
113 };
114 })
115static constexpr bool all_elements_model_totally_ordered_v =
116 decltype(detail::all_elements_model_totally_ordered(tuple_type_list_t<tuple_t>{}))::value;
117} // namespace bio::meta::detail
118
119namespace bio::meta
120{
121
122// ----------------------------------------------------------------------------
123// tuple_like
124// ----------------------------------------------------------------------------
125
174template <typename t>
175concept tuple_like = detail::tuple_size<std::remove_reference_t<t>> && requires(t v) {
176 typename detail::tuple_type_list<std::remove_cvref_t<t>>::type;
177
178 // NOTE(rrahn): To check the full tuple_concept including the get interface and the std::totally_ordered
179 // we need to make some assumptions. In general these checks can only be executed if the tuple is not
180 // empty. Furthermore, the std::totally_ordered can only be checked if all elements in the
181 // tuple are strict_totally_ordered. This is done, by the fold expression in the second part.
182 requires(std::tuple_size<std::remove_reference_t<t>>::value == 0) ||
183 (detail::tuple_get<std::remove_cvref_t<t>> &&
184 (!detail::all_elements_model_totally_ordered_v<std::remove_cvref_t<t>> ||
185 std::totally_ordered<std::remove_cvref_t<t>>));
186};
188
198template <typename t>
199concept pair_like = tuple_like<t> && std::tuple_size_v<std::remove_reference_t<t>> == 2;
200
201} // namespace bio::meta
Provides various type traits on generic types.
Whether a type behaves like a tuple with exactly two elements.
Definition: tuple.hpp:199
The Meta module's namespace.
Provides bio::meta::pod_tuple.
Provides various traits to inspect templates.
Provides bio::meta::type_list.