BioC++ core-0.7.0
The Modern C++ libraries for Bioinformatics.
 
Loading...
Searching...
No Matches
type_traits.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2022 deCODE Genetics
3// Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
4// Copyright (c) 2016-2020, 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 <iterator>
17#include <ranges>
18#include <type_traits>
19
20#include <bio/core.hpp>
22
23namespace bio::ranges::detail
24{
25
26// ----------------------------------------------------------------------------
27// iterator_category_tag
28// ----------------------------------------------------------------------------
29
30#if BIOCPP_WORKAROUND_GCC_96070
32template <typename it_t>
33struct iterator_category_tag
34{
35 using type = void;
36};
37
38template <typename it_t>
39 requires(requires { typename std::iterator_traits<it_t>::iterator_category; })
40struct iterator_category_tag<it_t>
41{
43};
45
55template <typename it_t>
56using iterator_category_tag_t = typename iterator_category_tag<it_t>::type;
57#else // ^^^ workaround / no workaround vvv
58// TODO: Change the description / the definition of iterator_category_tag_t depending on how the standard resolves this
59// https://github.com/seqan/product_backlog/issues/151
60
72template <typename it_t>
73 requires(requires { typename std::iterator_traits<it_t>::iterator_category; })
74using iterator_category_tag_t = typename std::iterator_traits<it_t>::iterator_category;
75#endif // BIOCPP_WORKAROUND_GCC_96070
76
77// ----------------------------------------------------------------------------
78// iterator_concept_tag_
79// ----------------------------------------------------------------------------
80
87template <typename it_t>
88 requires std::input_or_output_iterator<it_t>
89// clang-format off
90using iterator_concept_tag_t = std::conditional_t<std::contiguous_iterator<it_t>, std::contiguous_iterator_tag,
96// clang-format on
97
98// ----------------------------------------------------------------------------
99// iter_pointer
100// ----------------------------------------------------------------------------
101
112template <typename it_t>
113struct iter_pointer
114{
116 using type = void;
117};
118
120template <typename it_t>
121 requires(requires { typename std::iterator_traits<it_t>::pointer; })
122struct iter_pointer<it_t>
123{
126 using type = typename std::iterator_traits<it_t>::pointer;
127};
129
135template <typename it_t>
136using iter_pointer_t = typename iter_pointer<it_t>::type;
137
138template <typename t>
139concept has_range_value_type = requires { typename std::ranges::range_value_t<std::remove_cvref_t<t>>; };
140
141} // namespace bio::ranges::detail
142
143namespace bio::ranges
144{
145
150// ----------------------------------------------------------------------------
151// range_innermost_value
152// ----------------------------------------------------------------------------
153
154//NOTE(h-2): this could be moved to a separate file, because it also applies to iterators
155
164template <typename t>
165 requires detail::has_range_value_type<t>
167{
169 using type = std::ranges::range_value_t<std::remove_cvref_t<t>>;
170};
171
173template <typename t>
174 requires(detail::has_range_value_type<t> &&
175 detail::has_range_value_type<std::ranges::range_value_t<std::remove_cvref_t<t>>>)
177{
179};
181
184template <typename t>
186
187// ----------------------------------------------------------------------------
188// range_dimension_v
189// ----------------------------------------------------------------------------
190
199template <typename t>
200 requires detail::has_range_value_type<t>
201constexpr size_t range_dimension_v = 1;
202
204template <typename t>
205 requires(detail::has_range_value_type<t> &&
206 detail::has_range_value_type<std::ranges::range_value_t<std::remove_cvref_t<t>>>)
207constexpr size_t range_dimension_v<t> = range_dimension_v<std::ranges::range_value_t<std::remove_cvref_t<t>>> + 1;
209
210// ----------------------------------------------------------------------------
211// range_compatible
212// ----------------------------------------------------------------------------
213
225template <typename t1, typename t2>
226concept range_compatible = requires(t1, t2) {
227 requires(range_dimension_v<t1> == range_dimension_v<t2>);
228
229 requires std::is_same_v<range_innermost_value_t<t1>, range_innermost_value_t<t2>>;
230};
232
234
235} // namespace bio::ranges
Provides various type traits on generic types.
Provides platform and dependency checks.
constexpr size_t range_dimension_v
Returns the number of times you can call std::ranges::value_type_t recursively on t (type trait).
Definition: type_traits.hpp:201
typename range_innermost_value< t >::type range_innermost_value_t
Shortcut for bio::ranges::range_innermost_value (transformation_trait shortcut).
Definition: type_traits.hpp:185
The ranges module's namespace.
Recursively determines the value_type on containers and/or iterators.
Definition: type_traits.hpp:167
std::ranges::range_value_t< std::remove_cvref_t< t > > type
The return type (recursion not shown).
Definition: type_traits.hpp:169