#pragma once #include #include #include #include #include #include #include #include #include namespace mbgl { namespace util { template constexpr std::array convert(const std::array& from) requires(std::is_convertible_v) { std::array to{{}}; std::copy(std::begin(from), std::end(from), std::begin(to)); return to; } template constexpr std::array cast(const std::array& from) requires(std::is_assignable_v) { std::array to{{}}; std::transform(std::begin(from), std::end(from), std::begin(to), [](From x) { return static_cast(x); }); return to; } /// Convert an `N`-tuple of all `T`s to `array` template inline constexpr auto to_array(std::tuple&& tuple) { return std::apply([](auto&&... x) { return std::array{std::forward(x)...}; }, std::forward>(tuple)); } /// Convert string to integral types template std::enable_if_t, std::optional> parse(std::string_view str, int base = 10) noexcept { static_assert(std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v, "Unsupported integral type in mbgl::util::parse."); char* end = nullptr; errno = 0; if constexpr (std::is_same_v) { long val = std::strtol(str.data(), &end, base); // NOLINT(bugprone-suspicious-stringview-data-usage) if (errno == 0 && end == str.data() + str.size()) return static_cast(val); } else if constexpr (std::is_same_v) { unsigned long val = std::strtoul(str.data(), &end, base); // NOLINT(bugprone-suspicious-stringview-data-usage) if (errno == 0 && end == str.data() + str.size()) return static_cast(val); } else if constexpr (std::is_same_v) { long long val = std::strtoll(str.data(), &end, base); // NOLINT(bugprone-suspicious-stringview-data-usage) if (errno == 0 && end == str.data() + str.size()) return static_cast(val); } else if constexpr (std::is_same_v) { unsigned long long val = std::strtoull( str.data(), &end, base); // NOLINT(bugprone-suspicious-stringview-data-usage) if (errno == 0 && end == str.data() + str.size()) return static_cast(val); } return std::nullopt; } /// Convert string to floating point types template std::enable_if_t, std::optional> parse(std::string_view str) noexcept { static_assert(std::is_same_v || std::is_same_v || std::is_same_v, "Unsupported floating point type in mbgl::util::parse."); char* end = nullptr; errno = 0; if constexpr (std::is_same_v) { float val = std::strtof(str.data(), &end); // NOLINT(bugprone-suspicious-stringview-data-usage) if (errno == 0 && end == str.data() + str.size()) return val; } else if constexpr (std::is_same_v) { double val = std::strtod(str.data(), &end); // NOLINT(bugprone-suspicious-stringview-data-usage) if (errno == 0 && end == str.data() + str.size()) return val; } else if constexpr (std::is_same_v) { long double val = std::strtold(str.data(), &end); // NOLINT(bugprone-suspicious-stringview-data-usage) if (errno == 0 && end == str.data() + str.size()) return val; } return std::nullopt; } } // namespace util } // namespace mbgl