BioC++ core-0.7.0
The Modern C++ libraries for Bioinformatics.
 
Loading...
Searching...
No Matches
vtag.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 <numeric>
17#include <tuple>
18#include <type_traits>
19
20#include <bio/core.hpp>
23
24namespace bio::meta::detail
25{
26
38template <size_t capacity>
39struct literal_buffer_string : ranges::small_string<capacity>
40{
42 template <size_t N>
43 constexpr literal_buffer_string(char const (&_lit)[N]) noexcept : ranges::small_string<capacity>{_lit}
44 {}
45};
46
49template <size_t N>
50literal_buffer_string(char const (&)[N]) -> literal_buffer_string<N - 1>;
51
52} // namespace bio::meta::detail
53
54namespace bio::meta
55{
56
62template <auto... vs>
63struct vtag_t;
64
69template <>
70struct vtag_t<>
71{
73 static constexpr size_t size = 0;
74
76 static constexpr auto as_tuple = std::tuple{};
77
79 static consteval bool contains(auto &&) { return false; }
80
82 static consteval size_t index_of(auto &&) { return static_cast<size_t>(-1ULL); }
83
85 consteval friend bool operator==(vtag_t, vtag_t) noexcept { return true; }
86
88 consteval friend auto operator<=>(vtag_t, vtag_t) noexcept { return 0 <=> 0; }
89};
90
96template <auto v>
97struct vtag_t<v>
98{
100 static constexpr auto value = v;
101
103 static constexpr size_t size = 1;
104
106 static constexpr auto as_tuple = std::tuple{v};
107
109 static consteval bool contains(auto && s)
110 requires(weakly_equality_comparable_with<decltype(s), decltype(v)>)
111 {
112 return s == v;
113 }
114
116 static consteval size_t index_of(auto && s)
117 requires(weakly_equality_comparable_with<decltype(s), decltype(v)>)
118 {
119 return (s == v) ? 0ull : static_cast<size_t>(-1ull);
120 }
121
130 consteval auto operator-()
131 requires(arithmetic<decltype(v)>)
132 {
133 return vtag_t<-v>{};
134 }
135
137 template <auto v2>
138 consteval friend bool operator==(vtag_t, vtag_t<v2>) noexcept
139 requires weakly_equality_comparable_with<decltype(v), decltype(v2)>
140 {
141 return v == v2;
142 }
143
145 template <auto v2>
146 consteval friend auto operator<=>(vtag_t, vtag_t<v2>) noexcept
147 requires weakly_ordered_with<decltype(v), decltype(v2)>
148 {
149 return v <=> v2;
150 }
151};
152
158template <auto... vs>
159 requires(sizeof...(vs) >= 2)
160struct vtag_t<vs...>
161{
163 static constexpr size_t size = sizeof...(vs);
164
166 static constexpr auto as_tuple = std::tuple{vs...};
167
169 static consteval bool contains(auto && s)
170 requires((weakly_equality_comparable_with<decltype(s), decltype(vs)> && ...))
171 {
172 return ((s == vs) || ...);
173 }
174
176 static consteval size_t index_of(auto && s)
177 requires((weakly_equality_comparable_with<decltype(s), decltype(vs)> && ...))
178 {
179 size_t c = 0;
180 ((vs != s && ++c) && ...);
181 return c >= size ? static_cast<size_t>(-1ULL) : c;
182 }
183
185 template <auto... v2s>
186 consteval friend bool operator==(vtag_t, vtag_t<v2s...>) noexcept
187 requires(sizeof...(v2s) == size && (weakly_equality_comparable_with<decltype(vs), decltype(v2s)> && ...))
188 {
189 return vtag_t::as_tuple == vtag_t<v2s...>::as_tuple;
190 }
191
193 template <auto... v2s>
194 consteval friend auto operator<=>(vtag_t, vtag_t<v2s...>) noexcept
195 requires(sizeof...(v2s) == size && (weakly_ordered_with<decltype(vs), decltype(v2s)> && ...))
196 {
197 return vtag_t::as_tuple <=> vtag_t<v2s...>::as_tuple;
198 }
199};
200
215template <auto... vs>
216inline constexpr vtag_t<vs...> vtag{};
217
218inline namespace literals
219{
220
239template <detail::literal_buffer_string str>
240consteval auto operator""_vtag() noexcept
241{
242 return vtag<ranges::small_string<str.size()>{str}>;
243}
244
263template <char... chrs>
264consteval auto operator""_vtag() noexcept
265{
266 static_assert(((chrs >= '0' && chrs <= '9') && ...), "Only integral digits supported.");
267
268 constexpr int64_t val = []() constexpr
269 {
270 ranges::small_string str{chrs...};
271 int64_t ret = 0;
272 int64_t mult = 1;
273 // std::views::reverse is not constexpr on GCC10 :|
274 for (int64_t i = str.size() - 1; i >= 0; --i)
275 {
276 ret += (str[i] - '0') * mult;
277 mult *= 10;
278 }
279 return ret;
280 }();
281 return vtag<val>;
282}
283
284} // namespace literals
285
286} // namespace bio::meta
Implements a small string that can be used for compile time computations.
Definition: small_string.hpp:47
constexpr size_type size() const noexcept
Returns the number of elements in the container, i.e. std::distance(begin(), end()).
Definition: small_vector.hpp:467
A type that satisfies std::is_arithmetic_v<t>.
Definition: core_language.hpp:62
Requires the two operands to be comparable with == and != in both directions.
Definition: core_language.hpp:33
Requires the two operands to be comparable with <, <=, > and >= in both directions.
Definition: core_language.hpp:46
Provides platform and dependency checks.
Provides concepts for core language types and relations that don't have concepts in C++20 (yet).
constexpr vtag_t< vs... > vtag
A value-tag template.
Definition: vtag.hpp:216
The Meta module's namespace.
A constexpr string implementation to manipulate string literals at compile time.
consteval friend bool operator==(vtag_t, vtag_t< v2 >) noexcept
Compare 1-element vtag against 1-element vtag.
Definition: vtag.hpp:138
static consteval size_t index_of(auto &&s)
A function that returns the index of a value or ((size_t)-1) if the value is not found.
Definition: vtag.hpp:116
consteval friend auto operator<=>(vtag_t, vtag_t< v2 >) noexcept
Compare 1-element vtag against 1-element vtag.
Definition: vtag.hpp:146
consteval auto operator-()
Turns -vtag<3> into vtag<-3>.
Definition: vtag.hpp:130
static consteval bool contains(auto &&s)
A function that checks if a value is contained in the tag.
Definition: vtag.hpp:109
consteval friend bool operator==(vtag_t, vtag_t< v2s... >) noexcept
Compare n-element vtag against n-element vtag.
Definition: vtag.hpp:186
static consteval size_t index_of(auto &&s)
A function that returns the index of a value or ((size_t)-1) if the value is not found.
Definition: vtag.hpp:176
consteval friend auto operator<=>(vtag_t, vtag_t< v2s... >) noexcept
Compare n-element vtag against n-element vtag.
Definition: vtag.hpp:194
static consteval bool contains(auto &&s)
A function that checks if a value is contained in the tag.
Definition: vtag.hpp:169
static consteval size_t index_of(auto &&)
A function that returns the index of a value or ((size_t)-1) if the value is not found.
Definition: vtag.hpp:82
consteval friend bool operator==(vtag_t, vtag_t) noexcept
Compare 0-element vtag against 0-element vtag.
Definition: vtag.hpp:85
consteval friend auto operator<=>(vtag_t, vtag_t) noexcept
Compare 0-element vtag against 0-element vtag.
Definition: vtag.hpp:88
static consteval bool contains(auto &&)
A function that checks if a value is contained in the tag.
Definition: vtag.hpp:79
The type of bio::meta::vtag. [Declaration].
Definition: vtag.hpp:63