std::optional get_data_type()

in src/mlio-py/mlio/core/py_buffer.cc [112:220]


std::optional<Data_type> get_data_type(const py::buffer_info &info)
{
    const std::string &fmt_str = info.format;

    if (fmt_str.empty() || fmt_str.size() > 2) {
        return {};
    }

    char fmt = fmt_str[0];
    if (fmt_str.size() == 2) {
        if (fmt != '@' && fmt != '=') {
            return {};
        }

        fmt = fmt_str[1];
    }

    auto itemsize = static_cast<std::size_t>(info.itemsize);

    switch (fmt) {
    case 'N':
        if (itemsize == sizeof(std::size_t)) {
            return Data_type::size;
        }
        break;

    case 'e':
        if (itemsize == sizeof(std::uint16_t)) {
            return Data_type::float16;
        }
        break;

    case 'f':
        if (itemsize == sizeof(float)) {
            return Data_type::float32;
        }
        break;

    case 'd':
        if (itemsize == sizeof(double)) {
            return Data_type::float64;
        }
        break;

    case 'b':
        if (itemsize == sizeof(std::int8_t)) {
            return Data_type::int8;
        }
        break;
    case 'h':
        if (itemsize == sizeof(std::int16_t)) {
            return Data_type::int16;
        }
        break;
    case 'i':
        if (itemsize == sizeof(std::int32_t)) {
            return Data_type::int32;
        }
        break;
    case 'l':
        if (itemsize == sizeof(std::int32_t)) {
            return Data_type::int32;
        }
        else if (itemsize == sizeof(std::int64_t)) {
            return Data_type::int64;
        }
        break;
    case 'q':
        if (itemsize == sizeof(std::int64_t)) {
            return Data_type::int64;
        }
        break;
    case 'B':
        if (itemsize == sizeof(std::uint8_t)) {
            return Data_type::uint8;
        }
        break;
    case 'H':
        if (itemsize == sizeof(std::uint16_t)) {
            return Data_type::uint16;
        }
        break;
    case 'I':
        if (itemsize == sizeof(std::uint32_t)) {
            return Data_type::uint32;
        }
        break;
    case 'L':
        if (itemsize == sizeof(std::uint32_t)) {
            return Data_type::uint32;
        }
        else if (itemsize == sizeof(std::uint64_t)) {
            return Data_type::uint64;
        }
        break;
    case 'Q':
        if (itemsize == sizeof(std::uint64_t)) {
            return Data_type::uint64;
        }
        break;
    case 'O':
        if (itemsize == sizeof(PyObject *)) {
            return Data_type::string;
        }
        break;
    }

    return {};
}