|
8 | 8 |
|
9 | 9 | #pragma once |
10 | 10 |
|
| 11 | +#include <concepts> |
| 12 | +#include <tuple> |
| 13 | + |
| 14 | +#include <seqan3/utility/type_list/type_list.hpp> |
| 15 | + |
11 | 16 | #include <bio/platform.hpp> |
12 | 17 |
|
13 | 18 | /*!\file |
|
18 | 23 | namespace bio |
19 | 24 | { |
20 | 25 |
|
| 26 | +//----------------------------------------------------------------------------- |
| 27 | +// ownership |
| 28 | +//----------------------------------------------------------------------------- |
| 29 | + |
21 | 30 | /*!\brief An enum used as an argument for templates that switch between owning and non-owning behaviour. |
| 31 | + * \ingroup bio |
22 | 32 | * \details |
23 | 33 | * |
24 | 34 | * Typically used to configure a class template to have members that are vectors/strings VS members that are views. |
25 | 35 | * The "shallow" version of such a class is typically cheap to copy (no dynamic memory) while the "deep" version |
26 | | - * is exppensive to copy (holds dynamic memory). |
| 36 | + * is expensive to copy (holds dynamic memory). |
27 | 37 | */ |
28 | 38 | enum class ownership |
29 | 39 | { |
30 | | - shallow, //< Cheap to copy. |
31 | | - deep //< Expensive to copy. |
| 40 | + shallow, //!< Cheap to copy. |
| 41 | + deep //!< Expensive to copy. |
| 42 | +}; |
| 43 | + |
| 44 | +//----------------------------------------------------------------------------- |
| 45 | +// vtag |
| 46 | +//----------------------------------------------------------------------------- |
| 47 | + |
| 48 | +/*!\brief The type of bio::vtag. [Default "specialisation" for 0 arguments.] |
| 49 | + * \tparam more_vs Any number of values [only 0 arguments pick this specialisation]. |
| 50 | + * \ingroup bio |
| 51 | + * \see bio::vtag |
| 52 | + */ |
| 53 | +template <auto... more_vs> |
| 54 | +struct vtag_t |
| 55 | +{ |
| 56 | + //!\brief The number of values stored in the tag. |
| 57 | + static constexpr size_t size = 0; |
| 58 | + |
| 59 | + //!\brief The tag converted to a tuple. |
| 60 | + static constexpr auto as_tuple = std::tuple{}; |
| 61 | + |
| 62 | + //!\brief A function that checks if a value is contained in the tag. |
| 63 | + static constexpr bool contains(auto &&) { return false; } |
| 64 | + |
| 65 | + //!\brief A function that returns the index of a value or ((size_t)-1) if the value is not found. |
| 66 | + static constexpr size_t index_of(auto &&) { return static_cast<size_t>(-1ULL); } |
| 67 | +}; |
| 68 | + |
| 69 | +/*!\brief The type of bio::vtag. [Specialisation for 1 or more arguments] |
| 70 | + * \tparam v First value. |
| 71 | + * \tparam more_vs More values. |
| 72 | + * \ingroup bio |
| 73 | + * \see bio::vtag |
| 74 | + */ |
| 75 | +template <auto v, auto... more_vs> |
| 76 | +struct vtag_t<v, more_vs...> |
| 77 | +{ |
| 78 | + //!\brief The first value in the tag. |
| 79 | + static constexpr auto first_value = v; |
| 80 | + |
| 81 | + //!\copybrief bio::vtag_t::size |
| 82 | + static constexpr size_t size = sizeof...(more_vs) + 1; |
| 83 | + |
| 84 | + //!\copybrief bio::vtag_t::as_tuple |
| 85 | + static constexpr auto as_tuple = std::tuple{v, more_vs...}; |
| 86 | + |
| 87 | + //!\brief Whether all values in the tag are unique. |
| 88 | + static constexpr bool unique_values = ((v != more_vs) && ...); |
| 89 | + |
| 90 | + //!\copybrief bio::vtag_t::contains |
| 91 | + static constexpr bool contains(auto && s) requires std::equality_comparable_with<decltype(s), decltype(v)> && |
| 92 | + (std::equality_comparable_with<decltype(s), decltype(more_vs)> &&...) |
| 93 | + { |
| 94 | + return s == v || ((s == more_vs) || ...); |
| 95 | + } |
| 96 | + |
| 97 | + //!\copybrief bio::vtag_t::index_of |
| 98 | + static constexpr size_t index_of(auto && s) requires std::equality_comparable_with<decltype(s), decltype(v)> && |
| 99 | + (std::equality_comparable_with<decltype(s), decltype(more_vs)> &&...) |
| 100 | + { |
| 101 | + size_t c = 0; |
| 102 | + ((v != s && ++c) && ((more_vs != s && ++c) && ...)); |
| 103 | + return c >= size ? static_cast<size_t>(-1ULL) : c; |
| 104 | + } |
32 | 105 | }; |
33 | 106 |
|
| 107 | +/*!\brief A value-tag template. |
| 108 | + * \tparam vs The values to store in the tag. |
| 109 | + * \ingroup bio |
| 110 | + * \details |
| 111 | + * |
| 112 | + * Using this template, you can easily turn a value, e.g. a literal value, into a compile-time constant with a unique |
| 113 | + * type. |
| 114 | + * |
| 115 | + * ### Example |
| 116 | + * |
| 117 | + * \snippet test/snippet/snippet_tag.cpp vtag |
| 118 | + */ |
| 119 | +template <auto... vs> |
| 120 | +inline constexpr vtag_t<vs...> vtag{}; |
| 121 | + |
| 122 | +//----------------------------------------------------------------------------- |
| 123 | +// ttag |
| 124 | +//----------------------------------------------------------------------------- |
| 125 | + |
| 126 | +/*!\brief A type-tag template. |
| 127 | + * \tparam type The first type to store. |
| 128 | + * \tparam more_types More types to store (optional). |
| 129 | + * \ingroup bio |
| 130 | + * \see seqan3::type_list |
| 131 | + * |
| 132 | + * \details |
| 133 | + * |
| 134 | + * Using this template, you can easily turn a type into a compile-time constant (value). |
| 135 | + * |
| 136 | + * ### Example |
| 137 | + * |
| 138 | + * \snippet test/snippet/snippet_tag.cpp ttag |
| 139 | + */ |
| 140 | +template <typename type, typename... more_types> |
| 141 | +inline constexpr seqan3::type_list<type, more_types...> ttag{}; |
| 142 | + |
34 | 143 | } // namespace bio |
0 commit comments