Daily bit(e) C++. std::in_range

Добавлено 4 августа 2023 в 19:54

Daily bit(e) C++ #5, утилита std::in_range из C++20.

Daily bit(e) C++. std::in_range

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.

Теги

C++ / CppC++20Daily bit(e) C++STL / Standard Template Library / Стандартная библиотека шаблоновПрограммирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.