H3Error H3_EXPORT()

in h3_h3Index.c [1253:1323]


H3Error H3_EXPORT(cellToChildPos)(H3Index child, int parentRes, int64_t *out) {
    int childRes = H3_GET_RESOLUTION(child);
    // Get the parent at res. This will catch any resolution errors
    H3Index originalParent;
    H3Error parentError =
        H3_EXPORT(cellToParent(child, parentRes, &originalParent));
    if (parentError) {
        return parentError;
    }

    // Define the initial parent. Note that these variables are reassigned
    // within the loop.
    H3Index parent = originalParent;
    int parentIsPentagon = H3_EXPORT(isPentagon)(parent);

    // Walk up the resolution digits, incrementing the index
    *out = 0;
    if (parentIsPentagon) {
        // Pentagon logic. Pentagon parents skip the 1 digit, so the offsets are
        // different from hexagons
        for (int res = childRes; res > parentRes; res--) {
            H3Error parentError =
                H3_EXPORT(cellToParent(child, res - 1, &parent));
            if (NEVER(parentError)) {
                return parentError;
            }

            parentIsPentagon = H3_EXPORT(isPentagon)(parent);
            int rawDigit = H3_GET_INDEX_DIGIT(child, res);
            // Validate the digit before proceeding
            if (rawDigit == INVALID_DIGIT ||
                (parentIsPentagon && rawDigit == K_AXES_DIGIT)) {
                return E_CELL_INVALID;
            }
            int digit =
                parentIsPentagon && rawDigit > 0 ? rawDigit - 1 : rawDigit;
            if (digit != CENTER_DIGIT) {
                int64_t hexChildCount = _ipow(7, childRes - res);
                // The offset for the 0-digit slot depends on whether the
                // current index is the child of a pentagon. If so, the offset
                // is based on the count of pentagon children, otherwise,
                // hexagon children.
                *out += (parentIsPentagon
                             ?  // pentagon children. See the explanation
                                // for getNumCells in h3api.h.in
                             1 + (5 * (hexChildCount - 1)) / 6
                             :  // one hexagon's children
                             hexChildCount) +
                        // the other hexagon children
                        (digit - 1) * hexChildCount;
            }
        }
    } else {
        // Hexagon logic. Offsets are simple powers of 7
        for (int res = childRes; res > parentRes; res--) {
            int digit = H3_GET_INDEX_DIGIT(child, res);
            if (digit == INVALID_DIGIT) {
                return E_CELL_INVALID;
            }
            *out += digit * _ipow(7, childRes - res);
        }
    }

    if (NEVER(validateChildPos(*out, originalParent, childRes))) {
        // This is the result of an internal error, so return E_FAILED
        // instead of the validation error
        return E_FAILED;
    }

    return E_SUCCESS;
}