based

Opinionated 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

Diffstat:
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": [],