Program Listing for File fixed_name.hpp
↰ Return to documentation for file (utils/fixed_name.hpp
)
#pragma once
#include <string_view>
#include <array>
#include <optional>
#include <glaze/glaze.hpp>
template <size_t N>
struct FixedName {
std::array<char, N> buf{};
size_t len{};
FixedName() = default;
template <size_t M>
requires(M <= N)
constexpr FixedName(const char(&str)[M]) {
std::copy_n(str, M, buf.begin());
len = M - 1; // Exclude the null terminator from the length
}
struct glaze {
static constexpr auto value = [](const FixedName& self) -> auto { return std::string_view(self.buf.data(), self.len); };
};
bool operator==(const FixedName &other) const {
return std::string_view(other.buf.data(), other.len) == std::string_view(buf.data(), len);
}
auto operator<=>(const FixedName &other) const {
return std::string_view(buf.data(), len) <=> std::string_view(other.buf.data(), other.len);
}
explicit operator std::string_view() const {
return std::string_view(buf.data(), len);
}
const char* c_str() const {
return buf.data();
}
std::optional<FixedName> operator+(std::string_view other) const {
if (len + other.size() >= N) { // >= N because we need space for null terminato
return std::nullopt;
}
FixedName result;
result.len = len + other.size();
std::copy(buf.begin(), buf.begin() + len, result.buf.begin());
std::copy(other.begin(), other.end(), result.buf.begin() + len);
result.buf[result.len] = '\0'; // Ensure null-termination
return result;
}
bool operator+=(std::string_view other) {
if (len + other.size() >= N) { // >= N because we need space for null terminator
return false;
}
std::copy(other.begin(), other.end(), buf.begin() + len);
len += other.size();
buf[len] = '\0'; // Ensure null-termination
return true;
}
static std::optional<FixedName> init(std::string_view str) {
if (str.size() + 1 > N) { // +1 for the null terminator
return std::nullopt;
}
FixedName fn;
fn.len = str.size();
std::copy(str.begin(), str.end(), fn.buf.begin());
fn.buf[fn.len] = '\0'; // Ensure null-termination
return fn;
}
};
template <size_t N>
struct std::hash<FixedName<N>> {
std::size_t operator()(const FixedName<N>& k) const {
return hash(std::string_view(k));
}
};