SeqAn3 3.3.0-rc.1
The Modern C++ library for sequence analysis.
predicate_detail.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, Knut Reinert & MPI für molekulare Genetik
4// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6// -----------------------------------------------------------------------------------------------------
7
14#pragma once
15
16#include <array>
17#include <cctype>
18#include <concepts>
19#include <stdexcept>
20#include <string>
21
24
25namespace seqan3::detail
26{
27
28// ----------------------------------------------------------------------------
29// constexpr_pseudo_bitset (could be replaced with constexpr std::bitset or github.com/ClaasBontus/bitset2)
30// ----------------------------------------------------------------------------
31
36template <size_t N>
37class constexpr_pseudo_bitset : public std::array<bool, N>
38{
39private:
42
43public:
45 using base_t::base_t;
46
49 {
50 for (size_t i = 0; i < N; ++i)
51 rhs[i] = rhs[i] || base_t::operator[](i);
52
53 return rhs;
54 }
56 constexpr constexpr_pseudo_bitset operator~() const noexcept
57 {
59 for (size_t i = 0; i < N; ++i)
60 ret[i] = !base_t::operator[](i);
61
62 return ret;
63 }
64};
65
66// ----------------------------------------------------------------------------
67// condition_message_v
68// ----------------------------------------------------------------------------
69
78template <char op, typename condition_head_t, typename... condition_ts>
79inline const std::string condition_message_v{
80 std::string{"("}
81 + (condition_head_t::msg + ... + (std::string{" "} + std::string{{op, op}} + std::string{" "} + condition_ts::msg))
82 + std::string{")"}};
83
84// ----------------------------------------------------------------------------
85// char_predicate
86// ----------------------------------------------------------------------------
87
89template <typename condition_t>
90struct char_predicate_base;
92
103template <typename condition_t>
104concept char_predicate = requires {
105 requires std::predicate<std::remove_reference_t<condition_t>, char>;
106 requires std::is_base_of_v<char_predicate_base<std::remove_cvref_t<condition_t>>,
108
110
111 //The msg type can be added with a std::string.
112 {
114 } -> std::convertible_to<decltype(std::remove_reference_t<condition_t>::msg)>;
115 };
117
137
138// ----------------------------------------------------------------------------
139// char_predicate
140// ----------------------------------------------------------------------------
141
143template <char_predicate... condition_ts>
144 requires (sizeof...(condition_ts) >= 2)
145struct char_predicate_disjunction;
146
147template <char_predicate condition_t>
148struct char_predicate_negator;
150
157template <typename derived_t>
159{
161 using data_t = constexpr_pseudo_bitset<257>; // sizeof(char) plus EOF
162
168 template <char_predicate rhs_t>
169 constexpr auto operator||(rhs_t const &) const
170 {
172 }
173
175 constexpr auto operator!() const
176 {
178 }
180
185 template <std::integral value_t>
186 constexpr bool operator()(value_t const val) const noexcept
187 requires (sizeof(value_t) == 1)
188 {
189 return derived_t::data[static_cast<unsigned char>(val)];
190 }
191
193 template <std::integral value_t>
194 constexpr bool operator()(value_t const val) const noexcept
195 requires (sizeof(value_t) != 1)
196 {
197 using char_trait = std::char_traits<value_t>;
198 return (static_cast<std::make_unsigned_t<value_t>>(val) < 256) ? operator()(static_cast<uint8_t>(val))
199 : (char_trait::eq_int_type(val, char_trait::eof())) ? derived_t::data[256]
200 : false;
201 }
203
209 {
210 return derived_t::msg;
211 }
213};
214
215// ----------------------------------------------------------------------------
216// char_predicate_disjunction
217// ----------------------------------------------------------------------------
218
225template <char_predicate... condition_ts>
226 requires (sizeof...(condition_ts) >= 2)
227struct char_predicate_disjunction : public char_predicate_base<char_predicate_disjunction<condition_ts...>>
228{
230 static inline const std::string msg = detail::condition_message_v<'|', condition_ts...>;
231
234
236 using typename base_t::data_t;
238 static constexpr data_t data = (condition_ts::data | ...);
239};
240
247template <char_predicate condition_t>
248struct char_predicate_negator : public char_predicate_base<char_predicate_negator<condition_t>>
249{
251 static inline const std::string msg = std::string{'!'} + condition_t::msg;
252
255
257 using typename base_t::data_t;
259 static constexpr data_t data = ~condition_t::data;
260};
261
262// ----------------------------------------------------------------------------
263// is_in_interval_type
264// ----------------------------------------------------------------------------
265
274template <uint8_t interval_first, uint8_t interval_last>
275 requires (interval_first <= interval_last)
277{
279 static inline const std::string msg = std::string{"is_in_interval<'"} + std::string{interval_first}
280 + std::string{"', '"} + std::string{interval_last} + std::string{"'>"};
281
284
286 using typename base_t::data_t;
288 static constexpr data_t data = []() constexpr
289 {
290 data_t ret{};
291
292 for (size_t i = interval_first; i <= static_cast<size_t>(interval_last); ++i)
293 ret[i] = true;
294
295 return ret;
296 }
297 ();
298};
299
300// ----------------------------------------------------------------------------
301// is_char_type
302// ----------------------------------------------------------------------------
303
309template <int char_v>
310struct is_char_type : public char_predicate_base<is_char_type<char_v>>
311{
312 static_assert(char_v == EOF || static_cast<uint64_t>(char_v) < 256, "TODO");
313
315 static inline const std::string msg =
316 std::string{"is_char<'"} + ((char_v == EOF) ? std::string{"EOF"} : std::string{char_v}) + std::string{"'>"};
317
320
322 using typename base_t::data_t;
324 static constexpr data_t data = []() constexpr
325 {
326 data_t ret{};
327
328 if (char_v == EOF)
329 ret[256] = true;
330 else
331 ret[static_cast<uint8_t>(char_v)] = true;
332
333 return ret;
334 }
335 ();
336};
337
338} // namespace seqan3::detail
Provides various type traits on generic types.
A data structure that implements a subset of std::bitset as constexpr.
Definition: predicate_detail.hpp:38
constexpr constexpr_pseudo_bitset operator|(constexpr_pseudo_bitset rhs) const noexcept
Return a new bitset that is a logical disjunction of the two given ones.
Definition: predicate_detail.hpp:48
constexpr constexpr_pseudo_bitset operator~() const noexcept
Return a new bitset with all bits flipped.
Definition: predicate_detail.hpp:56
An internal concept to check if an object fulfills the requirements of a seqan3::detail::char_predica...
The internal SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
An abstract CRTP base class for parse conditions to add logical disjunction and negation operator.
Definition: predicate_detail.hpp:159
constexpr auto operator||(rhs_t const &) const
Combines the result of two seqan3::detail::char_predicate via logical disjunction.
Definition: predicate_detail.hpp:169
constexpr_pseudo_bitset< 257 > data_t
Type of the data field; as soon as std::bitset is fully constexpr, use that instead!
Definition: predicate_detail.hpp:161
std::string message() const
Returns the message representing this condition as std::string.
Definition: predicate_detail.hpp:208
constexpr bool operator()(value_t const val) const noexcept
Invokes the condition on val.
Definition: predicate_detail.hpp:186
constexpr bool operator()(value_t const val) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: predicate_detail.hpp:194
constexpr auto operator!() const
Return a new condition with all bits flipped.
Definition: predicate_detail.hpp:175
Logical disjunction operator for parse conditions.
Definition: predicate_detail.hpp:228
static const std::string msg
The message representing the disjunction of the associated conditions.
Definition: predicate_detail.hpp:230
static constexpr data_t data
The look-up table that is used to evaluate the input.
Definition: predicate_detail.hpp:238
Logical not operator for a parse condition.
Definition: predicate_detail.hpp:249
static const std::string msg
The message representing the negation of the associated condition.
Definition: predicate_detail.hpp:251
static constexpr data_t data
The look-up table that is used to evaluate the input.
Definition: predicate_detail.hpp:259
Parse condition that checks if a given value is equal to char_v.
Definition: predicate_detail.hpp:311
static const std::string msg
The message representing this condition.
Definition: predicate_detail.hpp:315
static constexpr data_t data
The look-up table that is used to evaluate the input.
Definition: predicate_detail.hpp:324
Parse condition that checks if a given value is in the range of rng_beg and interval_last.
Definition: predicate_detail.hpp:277
Provides traits to inspect some information of a type, for example its name.