#pragma once #include #include #include #include #include #include namespace cpp20 { template [[nodiscard]] auto double_value(T value) -> T { return value * 2; } template [[nodiscard]] auto clamp01(T value) -> T { // Converts the 0 and 1 to the right type, which fulfills the std::floating_point concept return std::clamp(value, T{0}, T{1}); } template concept StringLike = requires(T value) { { value.size() } -> std::convertible_to; { value.data() } -> std::convertible_to; }; template [[nodiscard]] auto uppercase_copy(const T& text) -> std::string { auto oss = std::ostringstream{}; for (auto idx = 0uz; idx < text.size(); idx++) { oss << static_cast(std::toupper(text.data()[idx])); } return oss.str(); } template requires std::integral [[nodiscard]] auto sum_integral(const std::vector& data) -> T { return std::ranges::fold_left(data, T{0}, std::plus{}); } } // namespace cpp20