Add utils::RangeToWrapper

This commit is contained in:
sha512sum 2024-10-29 12:17:08 +00:00
parent 15d4fd00d0
commit 405a3100e1
2 changed files with 43 additions and 21 deletions

View file

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <libxml++/libxml++.h> #include <libxml++/libxml++.h>
#include <algorithm> #include <larra/utils.hpp>
#include <nameof.hpp> #include <nameof.hpp>
#include <ranges> #include <ranges>
#include <variant> #include <variant>
@ -23,20 +23,18 @@ constexpr auto ToKebabCaseName() -> std::string_view {
static constexpr auto rawStr = nameof::nameof_short_type<T>(); static constexpr auto rawStr = nameof::nameof_short_type<T>();
constexpr auto str = [] { constexpr auto str = [] {
return rawStr | std::views::transform([](auto ch) { return rawStr //
| std::views::transform([](auto ch) {
return impl::IsUpper(ch) ? std::array<char, 2>{'-', impl::ToLower(ch)} : std::array<char, 2>{ch, '\0'}; return impl::IsUpper(ch) ? std::array<char, 2>{'-', impl::ToLower(ch)} : std::array<char, 2>{ch, '\0'};
}) | }) //
std::views::join | std::views::filter([](char ch) { | std::views::join //
| std::views::filter([](char ch) {
return ch != '\0'; return ch != '\0';
}); }) //
| std::views::drop(1);
}; };
constexpr auto size = std::ranges::distance(str()) - 1; static constexpr auto arr = str() | std::ranges::to<utils::RangeToWrapper<std::array<char, std::ranges::distance(str())>>>();
static constexpr auto arr = [&] { return {arr.data(), arr.size()};
std::array<char, size> response; // NOLINT
std::ranges::copy(str() | std::views::drop(1), response.begin());
return response;
}();
return {arr.data(), size};
} }
} // namespace impl } // namespace impl
@ -53,15 +51,11 @@ struct ErrorImpl : BaseError {
static inline const auto kKebabCaseName = static_cast<std::string>(impl::ToKebabCaseName<T>()); static inline const auto kKebabCaseName = static_cast<std::string>(impl::ToKebabCaseName<T>());
static constexpr auto kErrorMessage = [] -> std::string_view { static constexpr auto kErrorMessage = [] -> std::string_view {
static constexpr auto name = nameof::nameof_short_type<T>();
static constexpr auto str = [] { static constexpr auto str = [] {
return std::array{std::string_view{"Stream Error: "}, nameof::nameof_short_type<T>(), std::string_view{"\0", 1}} | std::views::join; return std::array{std::string_view{"Stream Error: "}, std::string_view{name}, std::string_view{"\0", 1}} | std::views::join;
}; };
constexpr auto size = std::ranges::distance(str()); static constexpr auto array = str() | std::ranges::to<utils::RangeToWrapper<std::array<char, std::ranges::distance(str())>>>();
static constexpr auto array = [&] {
std::array<char, size> response; // NOLINT
std::ranges::copy(str(), response.begin());
return response;
}();
return {array.data(), array.size() - 1}; return {array.data(), array.size() - 1};
}(); }();
static constexpr auto TryParse(xmlpp::Element* element) -> std::optional<T> { static constexpr auto TryParse(xmlpp::Element* element) -> std::optional<T> {

View file

@ -267,4 +267,32 @@ inline auto StartLifetimeAs(const void* ptr) -> const T* {
#endif #endif
// Example: "Hello" | std::ranges::to<RangeToWrapper<std::array<char, 6>>>()
template <typename T>
struct RangeToWrapper : T {
[[nodiscard]] constexpr auto Base() & -> decltype(auto) {
return static_cast<T&>(*this);
}
[[nodiscard]] constexpr auto Base() const& -> decltype(auto) {
return static_cast<const T&>(*this);
}
[[nodiscard]] constexpr auto Base() && -> decltype(auto) {
return static_cast<T&&>(*this);
}
[[nodiscard]] constexpr auto Base() const&& -> decltype(auto) {
return static_cast<const T&&>(*this);
}
template <typename Range> // NOLINTNEXTLINE
constexpr RangeToWrapper(std::from_range_t, Range&& range) {
auto result = std::ranges::copy(range, this->begin());
if(result.in != std::ranges::end(range) || result.out != std::ranges::end(*this)) {
throw std::invalid_argument{"Invalid range size"};
}
}
template <typename... Args> // NOLINTNEXTLINE
constexpr RangeToWrapper(Args&&... args)
requires requires { T{std::forward<Args>(args)...}; }
: T{std::forward<Args>(args)...} {};
};
} // namespace larra::xmpp::utils } // namespace larra::xmpp::utils