#include "serif/solver/normalization/detail/packing.hpp" #include #include #include #include "serif/utils/error/errors.hpp" namespace serif::solver::normalization::detail { namespace { /** @brief Preserve the declared block order while checking the total before allocating packed storage. */ [[nodiscard]] std::expected, std::string> pack_factors(std::span> coordinates) { using namespace utils::errors; std::size_t count = 0; for (const std::span factors : coordinates) { if (factors.size() > std::vector{}.max_size() - count) { return std::unexpected(format_error_message("The packed normalization layout exceeds the supported vector size. Reduce its coordinate counts.")); } count += factors.size(); } std::vector packed; packed.reserve(count); for (const std::span factors : coordinates) { packed.insert(packed.end(), factors.begin(), factors.end()); } return packed; } } std::expected pack_normalization(std::span> states, std::span> residuals) { auto state_factors = pack_factors(states); if (!state_factors) { return std::unexpected(state_factors.error()); } auto residual_factors = pack_factors(residuals); if (!residual_factors) { return std::unexpected(residual_factors.error()); } return make_diagonal_normalization(std::move(*state_factors), std::move(*residual_factors)); } }