BioC++ core-0.7.0
The Modern C++ libraries for Bioinformatics.
 
Loading...
Searching...
No Matches
traits_detail.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 <type_traits>
17#include <utility>
18
20
21// ----------------------------------------------------------------------------
22// bio::meta::detail::pack_traits::detail
23// ----------------------------------------------------------------------------
24
25namespace bio::meta::detail::pack_traits::detail
26{
27
34template <typename query_t, typename... pack_t>
35constexpr ptrdiff_t find()
36{
37 ptrdiff_t i = 0;
38 return ((std::is_same_v<query_t, pack_t> ? false : ++i) && ...) ? -1 : i;
39}
40
47template <template <typename> typename pred_t, typename... pack_t>
48constexpr ptrdiff_t find_if()
49{
50 ptrdiff_t i = 0;
51 return ((pred_t<pack_t>::value ? false : ++i) && ...) ? -1 : i;
52}
53
60template <ptrdiff_t idx, typename head_t, typename... tail_t>
61auto at()
62{
63 if constexpr (idx == 0)
65 else if constexpr (idx > 0)
66#ifdef __clang__
67 return std::type_identity<__type_pack_element<idx - 1, tail_t...>>{};
68#else
69 return at<idx - 1, tail_t...>();
70#endif // __clang__
71 else
72 return at<sizeof...(tail_t) + 1 + idx, head_t, tail_t...>();
73}
74
80template <typename head_t, typename... tail_t>
82
88template <typename head_t, typename... tail_t>
89type_list<tail_t...> drop_front();
90
98template <ptrdiff_t idx, typename head_t, typename... pack2_t, typename... pack1_t>
99auto split_after(type_list<pack1_t...>)
100{
101 if constexpr (idx == sizeof...(pack2_t) + 1)
102 return std::pair<type_list<pack1_t..., head_t, pack2_t...>, type_list<>>{};
103 else if constexpr (idx == 0)
104 return std::pair<type_list<pack1_t...>, type_list<head_t, pack2_t...>>{};
105 else
106 return split_after<idx - 1, pack2_t...>(type_list<pack1_t..., head_t>{});
107}
108
116template <typename replace_t, ptrdiff_t idx, typename... pack_t, size_t... i>
117auto replace_at(std::index_sequence<i...>) -> type_list<std::conditional_t<i == idx, replace_t, pack_t>...>;
118
119} // namespace bio::meta::detail::pack_traits::detail
120
121// ----------------------------------------------------------------------------
122// bio::meta::detail::pack_traits
123// ----------------------------------------------------------------------------
124
125namespace bio::meta::detail::pack_traits
126{
127
146template <typename... pack_t>
147inline constexpr size_t size = sizeof...(pack_t);
148
164template <typename query_t, typename... pack_t>
165inline constexpr ptrdiff_t count = (std::is_same_v<query_t, pack_t> + ... + 0);
166
182template <typename query_t, typename... pack_t>
183inline constexpr ptrdiff_t find = detail::find<query_t, pack_t...>();
184
205template <template <typename> typename pred_t, typename... pack_t>
206inline constexpr ptrdiff_t find_if = detail::find_if<pred_t, pack_t...>();
207
223template <typename query_t, typename... pack_t>
224inline constexpr bool contains = (find<query_t, pack_t...> != -1);
226
247template <ptrdiff_t idx, typename... pack_t>
248 requires((idx >= 0 && idx < sizeof...(pack_t)) || (-idx <= sizeof...(pack_t)))
249using at = typename decltype(detail::at<idx, pack_t...>())::type;
250
264template <typename... pack_t>
265 requires(sizeof...(pack_t) > 0)
266using front = typename decltype(detail::front<pack_t...>())::type;
267
284template <typename... pack_t>
285 requires(sizeof...(pack_t) > 0)
286using back = typename decltype((std::type_identity<pack_t>{}, ...))::type; // use comma operator
287
289
307template <typename... pack_t>
308 requires(sizeof...(pack_t) > 0)
309using drop_front = typename decltype(detail::drop_front<pack_t...>())::type;
310
328template <template <typename> typename trait_t, typename... pack_t>
329using transform = type_list<trait_t<pack_t>...>;
330
332
351template <ptrdiff_t i, typename... pack_t>
352 requires(i >= 0 && i <= size<pack_t...>)
353using take = typename decltype(detail::split_after<i, pack_t...>(type_list<>{}))::first_type;
354
369template <ptrdiff_t i, typename... pack_t>
370 requires(i >= 0 && i <= size<pack_t...>)
371using drop = typename decltype(detail::split_after<i, pack_t...>(type_list<>{}))::second_type;
372
387template <ptrdiff_t i, typename... pack_t>
388 requires(i >= 0 && i <= size<pack_t...>)
389using take_last = drop<size<pack_t...> - i, pack_t...>;
390
405template <ptrdiff_t i, typename... pack_t>
406 requires(i >= 0 && i <= size<pack_t...>)
407using drop_last = take<size<pack_t...> - i, pack_t...>;
408
423template <ptrdiff_t i, typename... pack_t>
424 requires(i >= 0 && i <= size<pack_t...>)
425using split_after = decltype(detail::split_after<i, pack_t...>(type_list<>{}));
426
442template <typename replace_t, std::ptrdiff_t i, typename... pack_t>
443 requires(i >= 0 && i < size<pack_t...>)
444using replace_at = decltype(detail::replace_at<replace_t, i, pack_t...>(std::make_index_sequence<size<pack_t...>>{}));
445
447
448} // namespace bio::meta::detail::pack_traits
constexpr auto size
A type trait that holds the size of a (semi-)alphabet.
Definition: concept.hpp:517
typename decltype(detail::at< idx >(list_t{}))::type at
Return the type at given index from the type list.
Definition: traits.hpp:309
typename decltype(detail::front(list_t{}))::type front
Return the first type from the type list.
Definition: traits.hpp:326
decltype(detail::split_after< i >(list_t{})) split_after
Split a meta::type_list into two parts returned as a pair of meta::type_list.
Definition: traits.hpp:479
take< size< list_t > - i, list_t > drop_last
Return a meta::type_list of the types the input type list, except the last n.
Definition: traits.hpp:461
decltype(detail::drop_front(list_t{})) drop_front
Return a meta::type_list of all the types in the type list, except the first.
Definition: traits.hpp:389
constexpr bool contains
Whether a type occurs in a type list or not.
Definition: traits.hpp:282
typename decltype(detail::split_after< i >(list_t{}))::first_type take
Return a meta::type_list of the first n types in the input type list.
Definition: traits.hpp:407
decltype(detail::replace_at< replace_t, i >(list_t{})) replace_at
Replace the type at the given index with the given type.
Definition: traits.hpp:519
Provides bio::meta::type_list.