Repository: matplotlib/matplotlib
File: src/_path.h (C/C++)

Code before:
        } catch (std::bad_alloc& e) {
            PyMem_Free(str);
            throw e;
        }
        PyMem_Free(str);
    }
}


template <class PathIterator>
bool __convert_to_string(PathIterator &path,
                         int precision,
                         std::array<std::string, 5> &codes,
                         bool postfix,
                         std::string& buffer)
{
    const char format_code = 'f';

    std::array<double, 3> x;
    std::array<double, 3> y;
    double last_x = 0.0;
    double last_y = 0.0;

    unsigned code;

    while ((code = path.vertex(&std::get<0>(x), &std::get<0>(y))) != agg::path_cmd_stop) {
        if (code == CLOSEPOLY) {
            buffer += std::get<4>(codes);
        } else if (code < 5) {
            size_t size = NUM_VERTICES[code];

            for (size_t i = 1; i < size; ++i) {
                unsigned subcode = path.vertex(&x.at(i), &y.at(i));
                if (subcode != code) {
                    return false;
                }
            }

            /* For formats that don't support quad curves, convert to
               cubic curves */
            if (code == CURVE3 && codes[code - 1][0] == '\0') {
                quad2cubic(last_x, last_y, x.at(0), y.at(0), x.at(1), y.at(1), x, y);
                code++;
                size = 3;
            }

            if (!postfix) {
                buffer += codes.at(code - 1);
                buffer += ' ';
            }


Review comment (suggestion):
I don't think the compiler can safely elide the bounds check here, because it'll have trouble proving that `size` is small enough (I guess the "modern C++" way of ensuring that is to make NUM_VERTICES an int templated on `code` etc.)

Code after:


template <class PathIterator>
bool __convert_to_string(PathIterator &path,
                         int precision,
                         const std::array<std::string, 5> &codes,
                         bool postfix,
                         std::string& buffer)
{
    const char format_code = 'f';

    std::array<double, 3> x;
    std::array<double, 3> y;
    double last_x = 0.0;
    double last_y = 0.0;

    unsigned code;

    while ((code = path.vertex(&std::get<0>(x), &std::get<0>(y))) != agg::path_cmd_stop) {
        if (code == CLOSEPOLY) {
            buffer += std::get<4>(codes);
        } else if (code < 5) {
            size_t size = NUM_VERTICES[code];

            for (size_t i = 1; i < size; ++i) {
                unsigned subcode = path.vertex(&x.at(i), &y.at(i));
                if (subcode != code) {
                    return false;
                }
            }

            /* For formats that don't support quad curves, convert to
               cubic curves */
            if (code == CURVE3 && codes[code - 1][0] == '\0') {
                quad2cubic(last_x, last_y, x.at(0), y.at(0), x.at(1), y.at(1), x, y);
                code++;
                size = 3;
            }

            if (!postfix) {
                buffer += codes.at(code - 1);
                buffer += ' ';
            }

            for (size_t i = 0; i < size; ++i) {
                __add_number(x.at(i), format_code, precision, buffer);
                buffer += ' ';
                __add_number(y.at(i), format_code, precision, buffer);
                buffer += ' ';
            }