Repository: microsoft/terminal
File: src/types/utils.cpp (C++)

Code before:
    auto success = false;
    if (wch >= L'0' && wch <= L'9')
    {
        value = wch - L'0';
        success = true;
    }
    else if (wch >= L'A' && wch <= L'F')
    {
        value = (wch - L'A') + 10;
        success = true;
    }
    else if (wch >= L'a' && wch <= L'f')
    {
        value = (wch - L'a') + 10;
        success = true;
    }
    return success;
}

// Routine Description:
// - Converts a number string to its equivalent unsigned integer value.
// Arguments:
// - wstr - String to convert.
// - value - receives the int value of the string
// Return Value:
// - true iff the string is a unsigned integer string.
bool Utils::StringToUint(const std::wstring_view wstr,
                         unsigned int& value)
{
    if (wstr.size() < 1)
    {
        return false;
    }

    unsigned int result = 0;
    size_t current = 0;
    while (current < wstr.size())
    {
        const auto wch = wstr.at(current);
        if (_isNumber(wch))
        {
            result *= 10;
            result += wch - L'0';

            ++current;
        }
        else
        {
            return false;
        }
    }

Review comment (suggestion):
Eventually, I will file a workitem for moving this stuff into til/color.h itself (not necessarily into the `color` class, mind). We have about three copies of the HSL/HLS code, and perhaps we can get it down to 1. :smile:

Code after:
    // so we need to scale our percentage values by 255/100. We can
    // optimise this conversion with a pre-created lookup table.
    static constexpr auto scale100To255 = [] {
        std::array<uint8_t, 101> lut{};
        for (size_t i = 0; i < std::size(lut); i++)
        {
            lut.at(i) = gsl::narrow_cast<uint8_t>((i * 255 + 50) / 100);
        }
        return lut;
    }();

    const auto red = til::at(scale100To255, std::min<unsigned>(r, 100u));
    const auto green = til::at(scale100To255, std::min<unsigned>(g, 100u));
    const auto blue = til::at(scale100To255, std::min<unsigned>(b, 100u));
    return { red, green, blue };
}

// Routine Description:
// - Constructs a til::color value from HLS components.
// Arguments:
// - h - The hue component of the color (0-360°).
// - l - The luminosity component of the color (0-100%).
// - s - The saturation component of the color (0-100%).
// Return Value:
// - The color defined by the given components.
til::color Utils::ColorFromHLS(const int h, const int l, const int s) noexcept
{
    const auto hue = h % 360;
    const auto lum = gsl::narrow_cast<float>(std::min(l, 100));
    const auto sat = gsl::narrow_cast<float>(std::min(s, 100));

    // This calculation is based on the HSL to RGB algorithm described in
    // Wikipedia: https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB
    // We start by calculating the chroma value, and the point along the bottom
    // faces of the RGB cube with the same hue and chroma as our color (x).
    const auto chroma = (50.f - abs(lum - 50.f)) * sat / 50.f;
    const auto x = chroma * (60 - abs(hue % 120 - 60)) / 60.f;

    // We'll also need an offset added to each component to match lightness.
    const auto lightness = lum - chroma / 2.0f;

    // We use the chroma value for the brightest component, x for the second
    // brightest, and 0 for the last. The values  are scaled by 255/100 to get
    // them in the range 0 to 255, as required by the color class.
    constexpr auto scale = 255.f / 100.f;
    const auto comp1 = gsl::narrow_cast<uint8_t>((chroma + lightness) * scale + 0.5f);
    const auto comp2 = gsl::narrow_cast<uint8_t>((x + lightness) * scale + 0.5f);
    const auto comp3 = gsl::narrow_cast<uint8_t>((0 + lightness) * scale + 0.5f);

    // Finally we order the components based on the given hue. But note that the
    // DEC terminals used a different mapping for hue than is typical for modern