Daily bit(e) C++. std::in_range
Добавлено 4 августа 2023 в 19:54
Daily bit(e) C++ #5, утилита std::in_range
из C++20.
std::in_range
– это простая утилита из C++20, которая проверяет, находится ли заданное значение в диапазоне заданного целочисленного типа.
Его можно использовать в качестве защиты, чтобы определить, будет ли целочисленное преобразование во время выполнения изменять значение.
#include <utility>
#include <iostream>
#include <concepts>
#include <cstdint>
// Пример защиты функции с ограниченной областью.
namespace {
// Фактическая реализация, которую необходимо защитить.
void some_func_impl(uint16_t v)
{
std::cout << "Actual called with \"" << v << "\"\n";
}
}
// Интерфейсная функция принимает любое целочисленное
// значение, гарантируя отсутствие преобразований.
void some_func(std::integral auto v)
{
if (!std::in_range<uint16_t>(v))
throw std::out_of_range("value out of range");
// Безопасное неявное преобразование
some_func_impl(v);
}
int main()
{
std::cout << "-1 in range of:\n";
std::cout << "\tint: " << std::boolalpha
<< std::in_range<int>(-1) << "\n";
std::cout << "\tunsigned: " << std::boolalpha
<< std::in_range<unsigned>(-1) << "\n";
std::cout << "\n";
try
{
// int, не в диапазоне uint16_t
some_func(-1);
}
catch(...)
{
std::cout << "Caught exception.\n";
}
try
{
// литерал size_t
some_func(2uz);
}
catch(...)
{
std::cout << "Caught exception.\n";
}
try
{
// int, не в диапазоне uint16_t
some_func(UINT16_MAX+1);
}
catch(...)
{
std::cout << "Caught exception.\n";
}
}
Вывод примера:
-1 in range of:
int: true
unsigned: false
Caught exception.
Actual called with "2"
Caught exception.
Открыть пример на Compiler Explorer.