Skip to content

Commit

Permalink
[REVIEW] char_predicate alternative
Browse files Browse the repository at this point in the history
  • Loading branch information
eseiler committed Nov 14, 2023
1 parent e786ca7 commit a73292b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 18 deletions.
20 changes: 16 additions & 4 deletions include/seqan3/utility/char_operations/predicate_detail.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <stdexcept>
#include <string>

#include <seqan3/utility/concept.hpp>
#include <seqan3/utility/detail/type_name_as_string.hpp>
#include <seqan3/utility/type_traits/basic.hpp>

Expand Down Expand Up @@ -194,10 +195,21 @@ struct char_predicate_base
constexpr bool operator()(value_t const val) const noexcept
requires (sizeof(value_t) != 1)
{
// std::char_traits is only defined for char types. libc++ deprecates other specialisations in llvm-17, and
// removes them in llvm-18. The int specialisation is needed for seqan3::is_eof(EOF).
using char_traits_value_t = std::conditional_t<std::same_as<value_t, int>, char, value_t>;
using char_trait = std::char_traits<char_traits_value_t>;
// std::char_traits is only guaranteed to be defined for character types.
// libc++ deprecates other specialisations in llvm-17, and removes them in llvm-18.
// We map the non-character types to corresponding chracter types.
// For example, `seqan3::is_eof(EOF)` will call this function with `value_t == int`.
// clang-format off
using char_value_t = std::conditional_t<seqan3::builtin_character<value_t>, value_t,
std::conditional_t<std::same_as<value_t, std::char_traits<char>::int_type>, char,
std::conditional_t<std::same_as<value_t, std::char_traits<wchar_t>::int_type>, wchar_t,
std::conditional_t<std::same_as<value_t, std::char_traits<char8_t>::int_type>, char8_t,
std::conditional_t<std::same_as<value_t, std::char_traits<char16_t>::int_type>, char16_t,
std::conditional_t<std::same_as<value_t, std::char_traits<char32_t>::int_type>, char32_t,
void>>>>>>;
// clang-format on
static_assert(!std::same_as<char_value_t, void>, "There is no valid character representation.");
using char_trait = std::char_traits<char_value_t>;
return (static_cast<std::make_unsigned_t<value_t>>(val) < 256) ? operator()(static_cast<uint8_t>(val))
: (char_trait::eq_int_type(val, char_trait::eof())) ? derived_t::data[256]
: false;
Expand Down
28 changes: 14 additions & 14 deletions test/snippet/utility/char_operations/char_predicate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,55 @@
int main()
{
//! [is_eof]
static_assert(seqan3::is_eof(EOF)); // returns true
static_assert(!seqan3::is_eof('C')); // returns false
static_assert(seqan3::is_eof(EOF));
static_assert(!seqan3::is_eof('C'));
//! [is_eof]

//! [is_cntrl]
static_assert(seqan3::is_cntrl('\0')); // returns true.
static_assert(seqan3::is_cntrl('\0'));
//! [is_cntrl]

//! [is_print]
static_assert(seqan3::is_print(' ')); // returns true.
static_assert(seqan3::is_print(' '));
//! [is_print]

//! [is_space]
static_assert(seqan3::is_space('\n')); // returns true.
static_assert(seqan3::is_space('\n'));
//! [is_space]

//! [is_blank]
static_assert(seqan3::is_blank('\t')); // returns true.
static_assert(seqan3::is_blank('\t'));
//! [is_blank]

//! [is_graph]
static_assert(seqan3::is_graph('%')); // returns true.
static_assert(seqan3::is_graph('%'));
//! [is_graph]

//! [is_punct]
static_assert(seqan3::is_punct(':')); // returns true.
static_assert(seqan3::is_punct(':'));
//! [is_punct]

//! [is_alnum]
static_assert(seqan3::is_alnum('9')); // returns true.
static_assert(seqan3::is_alnum('9'));
//! [is_alnum]

//! [is_alpha]
static_assert(seqan3::is_alpha('z')); // returns true.
static_assert(seqan3::is_alpha('z'));
//! [is_alpha]

//! [is_upper]
static_assert(seqan3::is_upper('K')); // returns true.
static_assert(seqan3::is_upper('K'));
//! [is_upper]

//! [is_lower]
static_assert(seqan3::is_lower('a')); // returns true.
static_assert(seqan3::is_lower('a'));
//! [is_lower]

//! [is_digit]
static_assert(seqan3::is_digit('1')); // returns true.
static_assert(seqan3::is_digit('1'));
//! [is_digit]

//! [is_xdigit]
static_assert(seqan3::is_xdigit('e')); // returns true.
static_assert(seqan3::is_xdigit('e'));
//! [is_xdigit]
}

0 comments on commit a73292b

Please sign in to comment.