basedOpinionated utility library |
git clone git://git.dimitrijedobrota.com/based.git |
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |
commit | cda6076429cb9a9ec7e504594bf4ef592edf55ba |
parent | d3258aa292b673d04de2314914c374cf04069537 |
author | Dimitrije Dobrota < mail@dimitrijedobrota.com > |
date | Sat, 31 May 2025 19:53:40 +0200 |
Map chars to ints based on predicate
A | include/based/char/mapper.hpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | test/CMakeLists.txt | | | ++++ |
A | test/source/char/mapper_test.cpp | | | +++++++++++++++++ |
3 files changed, 96 insertions(+), 0 deletions(-)
diff --git a/ include/based/char/mapper.hpp b/ include/based/char/mapper.hpp
@@ -0,0 +1,75 @@
#pragma once
#include <array>
#include "based/concepts/procedure/predicate.hpp"
#include "based/types/types.hpp"
namespace based
{
template<Predicate<char> Predicate>
class mapper
{
static constexpr based::size_t size = 128;
using mapped_type = bu8;
static constexpr Predicate m_predicate = {};
using direct_t = std::array<mapped_type, size>;
static constexpr direct_t direct = []
{
direct_t res = {};
mapped_type count = 0;
for (std::size_t idx = 0; idx < size; idx++) {
if (m_predicate(static_cast<char>(idx))) {
res[idx] = count++;
}
}
return res;
}();
static constexpr const std::size_t count = []
{
mapped_type count = 0;
for (std::size_t idx = 0; idx < size; idx++) {
if (m_predicate(static_cast<char>(idx))) {
count++;
}
}
return count;
}();
using reverse_t = std::array<char, count>;
static constexpr reverse_t reverse = []
{
reverse_t res = {};
mapped_type count = 0;
for (std::size_t idx = 0; idx < size; idx++) {
const auto chr = static_cast<char>(idx);
if (m_predicate(chr)) {
res[count++] = chr;
}
}
return res;
}();
public:
static constexpr bool predicate(char chr) { return m_predicate(chr); }
static constexpr char map(mapped_type value) { return reverse[value]; }
static constexpr mapped_type map(char chr)
{
return direct[static_cast<based::size_t>(chr)];
}
};
struct test
{
constexpr bool operator()(char chr) const { return chr >= 'a' && chr <= 'z'; }
};
} // namespace based
diff --git a/ test/CMakeLists.txt b/ test/CMakeLists.txt
@@ -83,6 +83,10 @@
add_test(. list_test)
add_test(. string_literal_test)
## ----- Char -----
add_test(char mapper_test)
# ---- End-of-file commands ----
add_folders(Test)
diff --git a/ test/source/char/mapper_test.cpp b/ test/source/char/mapper_test.cpp
@@ -0,0 +1,17 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include "based/char/mapper.hpp"
#include <catch2/catch_test_macros.hpp>
struct test
{
constexpr bool operator()(char chr) const { return chr >= '\0'; }
};
template class based::mapper<test>;
TEST_CASE("mapper", "[char/mapper]")
{
REQUIRE(true);
}