basedOpinionated utility library |
git clone git://git.dimitrijedobrota.com/based.git |
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |
commit | e2e839a3bc872c30a3de628a2d3caf72d95660aa |
parent | 04470f2869d8a31019270bfcdf41bc6cf8c974d5 |
author | Dimitrije Dobrota < mail@dimitrijedobrota.com > |
date | Wed, 11 Jun 2025 20:12:45 +0200 |
Static constexpr span and string_view
M | CMakeLists.txt | | | + - |
A | include/based/utility/make_static.hpp | | | +++++++++ |
A | include/based/utility/static_view.hpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | test/CMakeLists.txt | | | + |
A | test/source/utility/static_view_test.cpp | | | +++++++++++++++++++++++++++++ |
M | vcpkg.json | | | + - |
6 files changed, 116 insertions(+), 2 deletions(-)
diff --git a/ CMakeLists.txt b/ CMakeLists.txt
@@ -4,7 +4,7 @@
include(cmake/prelude.cmake)
project(
based
VERSION 0.2.0
VERSION 0.2.1
DESCRIPTION "Opinionated utility library"
HOMEPAGE_URL "https://git.dimitrijedobrota.com/based.git"
LANGUAGES CXX
diff --git a/ include/based/utility/make_static.hpp b/ include/based/utility/make_static.hpp
@@ -0,0 +1,9 @@
#pragma once
namespace based
{
template<auto data>
inline constexpr const auto& make_static = data;
} // namespace based
diff --git a/ include/based/utility/static_view.hpp b/ include/based/utility/static_view.hpp
@@ -0,0 +1,75 @@
#pragma once
#include <algorithm>
#include <array>
#include <span>
#include <string>
#include "based/utility/make_static.hpp"
namespace based
{
template<class T>
struct oversized_array
{
static constexpr auto oversized_size = static_cast<std::size_t>(10 * 1024);
using value_type = T;
std::array<T, oversized_size> data {};
std::size_t size {};
constexpr auto begin() { return std::begin(data); }
constexpr auto end()
{
return std::next(std::begin(data), static_cast<std::ptrdiff_t>(size));
}
[[nodiscard]] constexpr auto begin() const { return std::begin(data); }
[[nodiscard]] constexpr auto end() const
{
return std::next(std::begin(data), static_cast<std::ptrdiff_t>(size));
}
};
template<class Data>
consteval auto to_oversized_array(const Data& str)
{
oversized_array<typename Data::value_type> result;
std::ranges::copy(str, std::begin(result));
result.size = str.size();
return result;
}
constexpr auto to_right_sized_array(auto callable)
{
constexpr auto oversized = to_oversized_array(callable());
using value_type = typename std::decay_t<decltype(oversized)>::value_type;
std::array<value_type, oversized.size> result {};
std::ranges::copy(oversized, std::begin(result));
return result;
}
consteval auto to_string_view(auto callable)
{
constexpr auto& static_data = make_static<to_right_sized_array(callable)>;
using value_type = typename std::decay_t<decltype(static_data)>::value_type;
const std::basic_string_view<value_type> result = {
std::begin(static_data), std::end(static_data)
};
return result;
}
consteval auto to_span(auto callable)
{
constexpr auto& static_data = make_static<to_right_sized_array(callable)>;
using value_type = typename std::decay_t<decltype(static_data)>::value_type;
std::span<const value_type> result(static_data.begin(), static_data.end());
return result;
}
} // namespace based
diff --git a/ test/CMakeLists.txt b/ test/CMakeLists.txt
@@ -66,6 +66,7 @@
add_test(algorithms min_test)
add_test(utility buffer_test)
add_test(utility scopeguard_test)
add_test(utility static_view_test)
## ----- Functional -----
diff --git a/ test/source/utility/static_view_test.cpp b/ test/source/utility/static_view_test.cpp
@@ -0,0 +1,29 @@
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
#include <string>
#include "based/utility/static_view.hpp"
#include <catch2/catch_test_macros.hpp>
TEST_CASE("valid type", "[utility/to_string_view]")
{
static constexpr auto test = based::to_string_view(
[]() consteval
{
std::string res;
const auto start = 65;
const auto end = 122;
for (int i = start; i < end; i++) {
if (i % 2 == 1) {
res += static_cast<char>('\0' + i);
}
}
return res;
}
);
STATIC_REQUIRE(test == "ACEGIKMOQSUWY[]_acegikmoqsuwy");
}
diff --git a/ vcpkg.json b/ vcpkg.json
@@ -1,6 +1,6 @@
{
"name": "based",
"version-semver": "0.2.0",
"version-semver": "0.2.1",
"dependencies": [
],
"default-features": [],