Ежедневный бит (е) C++ # 5, утилита C++ 20 std::in_range

std::in_range — это простая утилита C++20, которая проверяет, находится ли заданное значение в диапазоне заданного целочисленного типа.

Его можно использовать в качестве защиты, чтобы определить, будет ли интегральное преобразование во время выполнения изменять значение.

#include <utility>
#include <concepts>
#include <cstdint>

bool v1 = std::in_range<int>(-1);
// v1 == true
bool v2 = std::in_range<unsigned>(-1);
// v2 == false

// Example of guarding a function with a limited domain.
namespace {
// Actual implementation that needs to be guarded.
void some_func_impl(uint16_t v) { }
}

// Interface function accepts any integral
// guaranteeing no value-changing conversions.
void some_func(std::integral auto v) {
    if (!std::in_range<uint16_t>(v))
        throw std::out_of_range("value out of range");

    // Safe implicit conversion
    some_func_impl(v);
}

// int, not in range of uint16_t
some_func(-1); // throws

// size_t literal, in range of uint16_t
some_func(2uz); // calls some_func_impl

// int, not in range of uint16_t
some_func(UINT16_MAX+1); // throws

Откройте пример в Compiler Explorer.