Add utils::RangeToWrapper
This commit is contained in:
parent
15d4fd00d0
commit
405a3100e1
2 changed files with 43 additions and 21 deletions
|
@ -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 //
|
||||||
return impl::IsUpper(ch) ? std::array<char, 2>{'-', impl::ToLower(ch)} : std::array<char, 2>{ch, '\0'};
|
| std::views::transform([](auto ch) {
|
||||||
}) |
|
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) {
|
}) //
|
||||||
return ch != '\0';
|
| std::views::join //
|
||||||
});
|
| std::views::filter([](char ch) {
|
||||||
|
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> {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue