LLVMFuzzerTestOneInput:
   29|    576|int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   30|    576|    if (size < sizeof(inputArgs)) {
  ------------------
  |  Branch (30:9): [True: 6, False: 570]
  ------------------
   31|      6|        return 0;
   32|      6|    }
   33|    570|    const inputArgs *args = (const inputArgs *)data;
   34|       |
   35|    570|    H3Index out;
   36|    570|    H3_EXPORT(cellToVertex)(args->index, args->vertexNum, &out);
  ------------------
  |  |   36|    570|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    570|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    570|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   37|    570|    H3Index outArr[6];
   38|    570|    H3_EXPORT(cellToVertexes)(args->index, outArr);
  ------------------
  |  |   36|    570|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    570|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    570|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   39|    570|    LatLng geo;
   40|    570|    H3_EXPORT(vertexToLatLng)(args->index, &geo);
  ------------------
  |  |   36|    570|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    570|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    570|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   41|    570|    H3_EXPORT(isValidVertex)(args->index);
  ------------------
  |  |   36|    570|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    570|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    570|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   42|    570|    return 0;
   43|    576|}

faceijk.c:_ijkToHex2d:
  244|    562|static inline void _ijkToHex2d(const CoordIJK *h, Vec2d *v) {
  245|    562|    int i = h->i - h->k;
  246|    562|    int j = h->j - h->k;
  247|       |
  248|    562|    v->x = i - 0.5 * j;
  249|    562|    v->y = j * M_SQRT3_2;
  ------------------
  |  |   44|    562|#define M_SQRT3_2 0.8660254037844386467637231707529361834714
  ------------------
  250|    562|}
faceijk.c:_ijkRotate60ccw:
  614|  16.2k|static inline void _ijkRotate60ccw(CoordIJK *ijk) {
  615|       |    // unit vector rotations
  616|  16.2k|    CoordIJK iVec = {1, 1, 0};
  617|  16.2k|    CoordIJK jVec = {0, 1, 1};
  618|  16.2k|    CoordIJK kVec = {1, 0, 1};
  619|       |
  620|  16.2k|    _ijkScale(&iVec, ijk->i);
  621|  16.2k|    _ijkScale(&jVec, ijk->j);
  622|  16.2k|    _ijkScale(&kVec, ijk->k);
  623|       |
  624|  16.2k|    _ijkAdd(&iVec, &jVec, ijk);
  625|  16.2k|    _ijkAdd(ijk, &kVec, ijk);
  626|       |
  627|  16.2k|    _ijkNormalize(ijk);
  628|  16.2k|}
faceijk.c:_ijkScale:
  155|  60.1k|static inline void _ijkScale(CoordIJK *c, int factor) {
  156|  60.1k|    c->i *= factor;
  157|  60.1k|    c->j *= factor;
  158|  60.1k|    c->k *= factor;
  159|  60.1k|}
faceijk.c:_ijkAdd:
  129|  45.7k|                           CoordIJK *sum) {
  130|  45.7k|    sum->i = h1->i + h2->i;
  131|  45.7k|    sum->j = h1->j + h2->j;
  132|  45.7k|    sum->k = h1->k + h2->k;
  133|  45.7k|}
faceijk.c:_ijkNormalize:
  207|  26.9k|static inline void _ijkNormalize(CoordIJK *c) {
  208|       |    // remove any negative values
  209|  26.9k|    if (c->i < 0) {
  ------------------
  |  Branch (209:9): [True: 0, False: 26.9k]
  ------------------
  210|      0|        c->j -= c->i;
  211|      0|        c->k -= c->i;
  212|      0|        c->i = 0;
  213|      0|    }
  214|       |
  215|  26.9k|    if (c->j < 0) {
  ------------------
  |  Branch (215:9): [True: 0, False: 26.9k]
  ------------------
  216|      0|        c->i -= c->j;
  217|      0|        c->k -= c->j;
  218|      0|        c->j = 0;
  219|      0|    }
  220|       |
  221|  26.9k|    if (c->k < 0) {
  ------------------
  |  Branch (221:9): [True: 0, False: 26.9k]
  ------------------
  222|      0|        c->i -= c->k;
  223|      0|        c->j -= c->k;
  224|      0|        c->k = 0;
  225|      0|    }
  226|       |
  227|       |    // remove the min value if needed
  228|  26.9k|    int min = c->i;
  229|  26.9k|    if (c->j < min) min = c->j;
  ------------------
  |  Branch (229:9): [True: 12.3k, False: 14.6k]
  ------------------
  230|  26.9k|    if (c->k < min) min = c->k;
  ------------------
  |  Branch (230:9): [True: 10.1k, False: 16.8k]
  ------------------
  231|  26.9k|    if (min > 0) {
  ------------------
  |  Branch (231:9): [True: 25.3k, False: 1.57k]
  ------------------
  232|  25.3k|        c->i -= min;
  233|  25.3k|        c->j -= min;
  234|  25.3k|        c->k -= min;
  235|  25.3k|    }
  236|  26.9k|}
faceijk.c:_downAp3:
  557|    562|static inline void _downAp3(CoordIJK *ijk) {
  558|       |    // res r unit vectors in res r+1
  559|    562|    CoordIJK iVec = {2, 0, 1};
  560|    562|    CoordIJK jVec = {1, 2, 0};
  561|    562|    CoordIJK kVec = {0, 1, 2};
  562|       |
  563|    562|    _ijkScale(&iVec, ijk->i);
  564|    562|    _ijkScale(&jVec, ijk->j);
  565|    562|    _ijkScale(&kVec, ijk->k);
  566|       |
  567|    562|    _ijkAdd(&iVec, &jVec, ijk);
  568|    562|    _ijkAdd(ijk, &kVec, ijk);
  569|       |
  570|    562|    _ijkNormalize(ijk);
  571|    562|}
faceijk.c:_downAp3r:
  579|    562|static inline void _downAp3r(CoordIJK *ijk) {
  580|       |    // res r unit vectors in res r+1
  581|    562|    CoordIJK iVec = {2, 1, 0};
  582|    562|    CoordIJK jVec = {0, 2, 1};
  583|    562|    CoordIJK kVec = {1, 0, 2};
  584|       |
  585|    562|    _ijkScale(&iVec, ijk->i);
  586|    562|    _ijkScale(&jVec, ijk->j);
  587|    562|    _ijkScale(&kVec, ijk->k);
  588|       |
  589|    562|    _ijkAdd(&iVec, &jVec, ijk);
  590|    562|    _ijkAdd(ijk, &kVec, ijk);
  591|       |
  592|    562|    _ijkNormalize(ijk);
  593|    562|}
faceijk.c:_downAp7r:
  534|    411|static inline void _downAp7r(CoordIJK *ijk) {
  535|       |    // res r unit vectors in res r+1
  536|    411|    CoordIJK iVec = {3, 1, 0};
  537|    411|    CoordIJK jVec = {0, 3, 1};
  538|    411|    CoordIJK kVec = {1, 0, 3};
  539|       |
  540|    411|    _ijkScale(&iVec, ijk->i);
  541|    411|    _ijkScale(&jVec, ijk->j);
  542|    411|    _ijkScale(&kVec, ijk->k);
  543|       |
  544|    411|    _ijkAdd(&iVec, &jVec, ijk);
  545|    411|    _ijkAdd(ijk, &kVec, ijk);
  546|       |
  547|    411|    _ijkNormalize(ijk);
  548|    411|}
faceijk.c:_setIJK:
  103|    525|static inline void _setIJK(CoordIJK *ijk, int i, int j, int k) {
  104|    525|    ijk->i = i;
  105|    525|    ijk->j = j;
  106|    525|    ijk->k = k;
  107|    525|}
faceijk.c:_ijkSub:
  143|    525|                           CoordIJK *diff) {
  144|    525|    diff->i = h1->i - h2->i;
  145|    525|    diff->j = h1->j - h2->j;
  146|    525|    diff->k = h1->k - h2->k;
  147|    525|}
faceijk.c:_ijkRotate60cw:
  635|    525|static inline void _ijkRotate60cw(CoordIJK *ijk) {
  636|       |    // unit vector rotations
  637|    525|    CoordIJK iVec = {1, 0, 1};
  638|    525|    CoordIJK jVec = {1, 1, 0};
  639|    525|    CoordIJK kVec = {0, 1, 1};
  640|       |
  641|    525|    _ijkScale(&iVec, ijk->i);
  642|    525|    _ijkScale(&jVec, ijk->j);
  643|    525|    _ijkScale(&kVec, ijk->k);
  644|       |
  645|    525|    _ijkAdd(&iVec, &jVec, ijk);
  646|    525|    _ijkAdd(ijk, &kVec, ijk);
  647|       |
  648|    525|    _ijkNormalize(ijk);
  649|    525|}
h3Index.c:_rotate60ccw:
  656|  13.7k|static inline Direction _rotate60ccw(Direction digit) {
  657|  13.7k|    switch (digit) {
  658|  2.64k|        case K_AXES_DIGIT:
  ------------------
  |  Branch (658:9): [True: 2.64k, False: 11.1k]
  ------------------
  659|  2.64k|            return IK_AXES_DIGIT;
  660|  2.44k|        case IK_AXES_DIGIT:
  ------------------
  |  Branch (660:9): [True: 2.44k, False: 11.3k]
  ------------------
  661|  2.44k|            return I_AXES_DIGIT;
  662|  2.05k|        case I_AXES_DIGIT:
  ------------------
  |  Branch (662:9): [True: 2.05k, False: 11.7k]
  ------------------
  663|  2.05k|            return IJ_AXES_DIGIT;
  664|  1.96k|        case IJ_AXES_DIGIT:
  ------------------
  |  Branch (664:9): [True: 1.96k, False: 11.8k]
  ------------------
  665|  1.96k|            return J_AXES_DIGIT;
  666|  2.04k|        case J_AXES_DIGIT:
  ------------------
  |  Branch (666:9): [True: 2.04k, False: 11.7k]
  ------------------
  667|  2.04k|            return JK_AXES_DIGIT;
  668|  2.46k|        case JK_AXES_DIGIT:
  ------------------
  |  Branch (668:9): [True: 2.46k, False: 11.3k]
  ------------------
  669|  2.46k|            return K_AXES_DIGIT;
  670|    190|        default:
  ------------------
  |  Branch (670:9): [True: 190, False: 13.6k]
  ------------------
  671|    190|            return digit;
  672|  13.7k|    }
  673|  13.7k|}
h3Index.c:_rotate60cw:
  680|  9.08k|static inline Direction _rotate60cw(Direction digit) {
  681|  9.08k|    switch (digit) {
  682|  1.17k|        case K_AXES_DIGIT:
  ------------------
  |  Branch (682:9): [True: 1.17k, False: 7.90k]
  ------------------
  683|  1.17k|            return JK_AXES_DIGIT;
  684|    986|        case JK_AXES_DIGIT:
  ------------------
  |  Branch (684:9): [True: 986, False: 8.09k]
  ------------------
  685|    986|            return J_AXES_DIGIT;
  686|    753|        case J_AXES_DIGIT:
  ------------------
  |  Branch (686:9): [True: 753, False: 8.32k]
  ------------------
  687|    753|            return IJ_AXES_DIGIT;
  688|  1.17k|        case IJ_AXES_DIGIT:
  ------------------
  |  Branch (688:9): [True: 1.17k, False: 7.90k]
  ------------------
  689|  1.17k|            return I_AXES_DIGIT;
  690|  1.26k|        case I_AXES_DIGIT:
  ------------------
  |  Branch (690:9): [True: 1.26k, False: 7.82k]
  ------------------
  691|  1.26k|            return IK_AXES_DIGIT;
  692|  1.86k|        case IK_AXES_DIGIT:
  ------------------
  |  Branch (692:9): [True: 1.86k, False: 7.21k]
  ------------------
  693|  1.86k|            return K_AXES_DIGIT;
  694|  1.86k|        default:
  ------------------
  |  Branch (694:9): [True: 1.86k, False: 7.21k]
  ------------------
  695|  1.86k|            return digit;
  696|  9.08k|    }
  697|  9.08k|}
h3Index.c:_downAp7:
  512|  39.5k|static inline void _downAp7(CoordIJK *ijk) {
  513|       |    // res r unit vectors in res r+1
  514|  39.5k|    CoordIJK iVec = {3, 0, 1};
  515|  39.5k|    CoordIJK jVec = {1, 3, 0};
  516|  39.5k|    CoordIJK kVec = {0, 1, 3};
  517|       |
  518|  39.5k|    _ijkScale(&iVec, ijk->i);
  519|  39.5k|    _ijkScale(&jVec, ijk->j);
  520|  39.5k|    _ijkScale(&kVec, ijk->k);
  521|       |
  522|  39.5k|    _ijkAdd(&iVec, &jVec, ijk);
  523|  39.5k|    _ijkAdd(ijk, &kVec, ijk);
  524|       |
  525|  39.5k|    _ijkNormalize(ijk);
  526|  39.5k|}
h3Index.c:_ijkScale:
  155|   236k|static inline void _ijkScale(CoordIJK *c, int factor) {
  156|   236k|    c->i *= factor;
  157|   236k|    c->j *= factor;
  158|   236k|    c->k *= factor;
  159|   236k|}
h3Index.c:_ijkAdd:
  129|   213k|                           CoordIJK *sum) {
  130|   213k|    sum->i = h1->i + h2->i;
  131|   213k|    sum->j = h1->j + h2->j;
  132|   213k|    sum->k = h1->k + h2->k;
  133|   213k|}
h3Index.c:_upAp7r:
  494|  2.83k|static inline void _upAp7r(CoordIJK *ijk) {
  495|       |    // convert to CoordIJ
  496|  2.83k|    int i = ijk->i - ijk->k;
  497|  2.83k|    int j = ijk->j - ijk->k;
  498|       |
  499|  2.83k|    ijk->i = (int)lround((2 * i + j) * M_ONESEVENTH);
  ------------------
  |  |   54|  2.83k|#define M_ONESEVENTH 0.14285714285714285714285714285714285
  ------------------
  500|  2.83k|    ijk->j = (int)lround((3 * j - i) * M_ONESEVENTH);
  ------------------
  |  |   54|  2.83k|#define M_ONESEVENTH 0.14285714285714285714285714285714285
  ------------------
  501|  2.83k|    ijk->k = 0;
  502|  2.83k|    _ijkNormalize(ijk);
  503|  2.83k|}
h3Index.c:_downAp7r:
  534|  39.3k|static inline void _downAp7r(CoordIJK *ijk) {
  535|       |    // res r unit vectors in res r+1
  536|  39.3k|    CoordIJK iVec = {3, 1, 0};
  537|  39.3k|    CoordIJK jVec = {0, 3, 1};
  538|  39.3k|    CoordIJK kVec = {1, 0, 3};
  539|       |
  540|  39.3k|    _ijkScale(&iVec, ijk->i);
  541|  39.3k|    _ijkScale(&jVec, ijk->j);
  542|  39.3k|    _ijkScale(&kVec, ijk->k);
  543|       |
  544|  39.3k|    _ijkAdd(&iVec, &jVec, ijk);
  545|  39.3k|    _ijkAdd(ijk, &kVec, ijk);
  546|       |
  547|  39.3k|    _ijkNormalize(ijk);
  548|  39.3k|}
h3Index.c:_ijkNormalize:
  207|   137k|static inline void _ijkNormalize(CoordIJK *c) {
  208|       |    // remove any negative values
  209|   137k|    if (c->i < 0) {
  ------------------
  |  Branch (209:9): [True: 1.00k, False: 136k]
  ------------------
  210|  1.00k|        c->j -= c->i;
  211|  1.00k|        c->k -= c->i;
  212|  1.00k|        c->i = 0;
  213|  1.00k|    }
  214|       |
  215|   137k|    if (c->j < 0) {
  ------------------
  |  Branch (215:9): [True: 1.05k, False: 136k]
  ------------------
  216|  1.05k|        c->i -= c->j;
  217|  1.05k|        c->k -= c->j;
  218|  1.05k|        c->j = 0;
  219|  1.05k|    }
  220|       |
  221|   137k|    if (c->k < 0) {
  ------------------
  |  Branch (221:9): [True: 0, False: 137k]
  ------------------
  222|      0|        c->i -= c->k;
  223|      0|        c->j -= c->k;
  224|      0|        c->k = 0;
  225|      0|    }
  226|       |
  227|       |    // remove the min value if needed
  228|   137k|    int min = c->i;
  229|   137k|    if (c->j < min) min = c->j;
  ------------------
  |  Branch (229:9): [True: 89.6k, False: 47.5k]
  ------------------
  230|   137k|    if (c->k < min) min = c->k;
  ------------------
  |  Branch (230:9): [True: 35.5k, False: 101k]
  ------------------
  231|   137k|    if (min > 0) {
  ------------------
  |  Branch (231:9): [True: 89.7k, False: 47.3k]
  ------------------
  232|  89.7k|        c->i -= min;
  233|  89.7k|        c->j -= min;
  234|  89.7k|        c->k -= min;
  235|  89.7k|    }
  236|   137k|}
h3Index.c:_neighbor:
  602|  73.4k|static inline void _neighbor(CoordIJK *ijk, Direction digit) {
  603|  73.4k|    if (digit > CENTER_DIGIT && digit < NUM_DIGITS) {
  ------------------
  |  Branch (603:9): [True: 59.1k, False: 14.3k]
  |  Branch (603:33): [True: 55.4k, False: 3.67k]
  ------------------
  604|  55.4k|        _ijkAdd(ijk, &UNIT_VECS[digit], ijk);
  605|  55.4k|        _ijkNormalize(ijk);
  606|  55.4k|    }
  607|  73.4k|}

faceijk.c:vec3LinComb:
   65|  1.68k|static inline Vec3d vec3LinComb(double a, Vec3d v1, double b, Vec3d v2) {
   66|  1.68k|    Vec3d out = {
   67|  1.68k|        .x = a * v1.x + b * v2.x,
   68|  1.68k|        .y = a * v1.y + b * v2.y,
   69|  1.68k|        .z = a * v1.z + b * v2.z,
   70|  1.68k|    };
   71|  1.68k|    return out;
   72|  1.68k|}
faceijk.c:vec3NormSq:
   87|  1.12k|static inline double vec3NormSq(Vec3d v) { return vec3Dot(v, v); }
faceijk.c:vec3Dot:
   83|  1.68k|static inline double vec3Dot(Vec3d v1, Vec3d v2) {
   84|  1.68k|    return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
   85|  1.68k|}
faceijk.c:vec3Cross:
   74|    562|static inline Vec3d vec3Cross(Vec3d v1, Vec3d v2) {
   75|    562|    Vec3d out = {
   76|    562|        .x = v1.y * v2.z - v1.z * v2.y,
   77|    562|        .y = v1.z * v2.x - v1.x * v2.z,
   78|    562|        .z = v1.x * v2.y - v1.y * v2.x,
   79|    562|    };
   80|    562|    return out;
   81|    562|}
faceijk.c:vec3Normalize:
   91|  1.12k|static inline void vec3Normalize(Vec3d *v) {
   92|  1.12k|    double norm = vec3Norm(*v);
   93|       |
   94|       |    // Norm can be zero either from true zero vector, or from squaring
   95|       |    // underflowing to zero.
   96|       |    // If the norm is nonzero, we normalize v using it.
   97|       |    // If the norm is zero, we set the vector to be exactly zero.
   98|  1.12k|    double s = 0.0;
   99|  1.12k|    if (norm > 0.0) {
  ------------------
  |  Branch (99:9): [True: 1.12k, False: 0]
  ------------------
  100|  1.12k|        s = 1.0 / norm;
  101|  1.12k|    }
  102|       |
  103|  1.12k|    v->x *= s;
  104|  1.12k|    v->y *= s;
  105|  1.12k|    v->z *= s;
  106|  1.12k|}
faceijk.c:vec3Norm:
   89|  1.12k|static inline double vec3Norm(Vec3d v) { return sqrt(vec3NormSq(v)); }
faceijk.c:vec3ToLatLng:
   54|    562|static inline LatLng vec3ToLatLng(Vec3d v) {
   55|    562|    LatLng out = {
   56|       |        // atan2 rather than asin(z): near the poles asin loses about
   57|       |        // 1/cos(lat) in precision because it recovers cos(lat) from 1 - z^2,
   58|       |        // while sqrt(x^2 + y^2) is cos(lat) at full precision.
   59|    562|        .lat = atan2(v.z, sqrt(v.x * v.x + v.y * v.y)),
   60|    562|        .lng = atan2(v.y, v.x),
   61|    562|    };
   62|    562|    return out;
   63|    562|}

h3NeighborRotations:
  458|  5.58k|                            H3Index *out) {
  459|  5.58k|    H3Index current = origin;
  460|       |
  461|  5.58k|    if (dir < CENTER_DIGIT || dir >= INVALID_DIGIT) {
  ------------------
  |  Branch (461:9): [True: 0, False: 5.58k]
  |  Branch (461:31): [True: 0, False: 5.58k]
  ------------------
  462|      0|        return E_FAILED;
  463|      0|    }
  464|       |    // Ensure that rotations is modulo'd by 6 before any possible addition,
  465|       |    // to protect against signed integer overflow.
  466|  5.58k|    *rotations = *rotations % 6;
  467|  5.58k|    for (int i = 0; i < *rotations; i++) {
  ------------------
  |  Branch (467:21): [True: 0, False: 5.58k]
  ------------------
  468|      0|        dir = _rotate60ccw(dir);
  469|      0|    }
  470|       |
  471|  5.58k|    int newRotations = 0;
  472|  5.58k|    int oldBaseCell = H3_GET_BASE_CELL(current);
  ------------------
  |  |  118|  5.58k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  5.58k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  5.58k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  5.58k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  473|  5.58k|    if (NEVER(oldBaseCell < 0) || oldBaseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |  119|  11.1k|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 5.58k]
  |  |  |  Branch (119:19): [True: 0, False: 5.58k]
  |  |  ------------------
  ------------------
                  if (NEVER(oldBaseCell < 0) || oldBaseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |   81|  5.58k|#define NUM_BASE_CELLS 122
  ------------------
  |  Branch (473:9): [Folded, False: 0]
  |  Branch (473:9): [Folded, False: 0]
  |  Branch (473:35): [True: 0, False: 5.58k]
  ------------------
  474|       |        // Base cells less than zero can not be represented in an index
  475|      0|        return E_CELL_INVALID;
  476|      0|    }
  477|  5.58k|    Direction oldLeadingDigit = _h3LeadingNonZeroDigit(current);
  478|       |
  479|       |    // Adjust the indexing digits and, if needed, the base cell.
  480|  5.58k|    int r = H3_GET_RESOLUTION(current) - 1;
  ------------------
  |  |  129|  5.58k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  5.58k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  5.58k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  5.58k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  481|  15.7k|    while (true) {
  ------------------
  |  Branch (481:12): [True: 15.7k, Folded]
  ------------------
  482|  15.7k|        if (r == -1) {
  ------------------
  |  Branch (482:13): [True: 1.49k, False: 14.2k]
  ------------------
  483|  1.49k|            H3_SET_BASE_CELL(current, baseCellNeighbors[oldBaseCell][dir]);
  ------------------
  |  |  124|  1.49k|    (h3) = (((h3)&H3_BC_MASK_NEGATIVE) | (((uint64_t)(bc)) << H3_BC_OFFSET))
  |  |  ------------------
  |  |  |  |   65|  1.49k|#define H3_BC_MASK_NEGATIVE (~H3_BC_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   62|  1.49k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  1.49k|#define H3_BC_OFFSET 45
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (h3) = (((h3)&H3_BC_MASK_NEGATIVE) | (((uint64_t)(bc)) << H3_BC_OFFSET))
  |  |  ------------------
  |  |  |  |   38|  1.49k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  484|  1.49k|            newRotations = baseCellNeighbor60CCWRots[oldBaseCell][dir];
  485|       |
  486|  1.49k|            if (H3_GET_BASE_CELL(current) == INVALID_BASE_CELL) {
  ------------------
  |  |  118|  1.49k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  1.49k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  1.49k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  1.49k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
                          if (H3_GET_BASE_CELL(current) == INVALID_BASE_CELL) {
  ------------------
  |  |   38|  1.49k|#define INVALID_BASE_CELL 127
  ------------------
  |  Branch (486:17): [True: 60, False: 1.43k]
  ------------------
  487|       |                // Adjust for the deleted k vertex at the base cell level.
  488|       |                // This edge actually borders a different neighbor.
  489|     60|                H3_SET_BASE_CELL(current,
  ------------------
  |  |  124|     60|    (h3) = (((h3)&H3_BC_MASK_NEGATIVE) | (((uint64_t)(bc)) << H3_BC_OFFSET))
  |  |  ------------------
  |  |  |  |   65|     60|#define H3_BC_MASK_NEGATIVE (~H3_BC_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   62|     60|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|     60|#define H3_BC_OFFSET 45
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (h3) = (((h3)&H3_BC_MASK_NEGATIVE) | (((uint64_t)(bc)) << H3_BC_OFFSET))
  |  |  ------------------
  |  |  |  |   38|     60|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  490|     60|                                 baseCellNeighbors[oldBaseCell][IK_AXES_DIGIT]);
  491|     60|                newRotations =
  492|     60|                    baseCellNeighbor60CCWRots[oldBaseCell][IK_AXES_DIGIT];
  493|       |
  494|       |                // perform the adjustment for the k-subsequence we're skipping
  495|       |                // over.
  496|     60|                current = _h3Rotate60ccw(current);
  497|     60|                *rotations = *rotations + 1;
  498|     60|            }
  499|       |
  500|  1.49k|            break;
  501|  14.2k|        } else {
  502|  14.2k|            Direction oldDigit = H3_GET_INDEX_DIGIT(current, r + 1);
  ------------------
  |  |  141|  14.2k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  14.2k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  14.2k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  14.2k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  14.2k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  503|  14.2k|            Direction nextDir;
  504|  14.2k|            if (oldDigit == INVALID_DIGIT) {
  ------------------
  |  Branch (504:17): [True: 98, False: 14.1k]
  ------------------
  505|       |                // Only possible on invalid input
  506|     98|                return E_CELL_INVALID;
  507|  14.1k|            } else if (isResolutionClassIII(r + 1)) {
  ------------------
  |  Branch (507:24): [True: 8.19k, False: 5.91k]
  ------------------
  508|  8.19k|                H3_SET_INDEX_DIGIT(current, r + 1, NEW_DIGIT_II[oldDigit][dir]);
  ------------------
  |  |  162|  8.19k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  8.19k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  8.19k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  8.19k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  8.19k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  8.19k|            (((uint64_t)(digit))                                            \
  |  |  165|  8.19k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  8.19k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  8.19k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  ------------------
  509|  8.19k|                nextDir = NEW_ADJUSTMENT_II[oldDigit][dir];
  510|  8.19k|            } else {
  511|  5.91k|                H3_SET_INDEX_DIGIT(current, r + 1,
  ------------------
  |  |  162|  5.91k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  5.91k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  5.91k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  5.91k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  5.91k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  5.91k|            (((uint64_t)(digit))                                            \
  |  |  165|  5.91k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  5.91k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  5.91k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  ------------------
  512|  5.91k|                                   NEW_DIGIT_III[oldDigit][dir]);
  513|  5.91k|                nextDir = NEW_ADJUSTMENT_III[oldDigit][dir];
  514|  5.91k|            }
  515|       |
  516|  14.1k|            if (nextDir != CENTER_DIGIT) {
  ------------------
  |  Branch (516:17): [True: 10.1k, False: 3.99k]
  ------------------
  517|  10.1k|                dir = nextDir;
  518|  10.1k|                r--;
  519|  10.1k|            } else {
  520|       |                // No more adjustment to perform
  521|  3.99k|                break;
  522|  3.99k|            }
  523|  14.1k|        }
  524|  15.7k|    }
  525|       |
  526|  5.48k|    int newBaseCell = H3_GET_BASE_CELL(current);
  ------------------
  |  |  118|  5.48k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  5.48k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  5.48k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  5.48k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  527|  5.48k|    if (_isBaseCellPentagon(newBaseCell)) {
  ------------------
  |  Branch (527:9): [True: 2.59k, False: 2.89k]
  ------------------
  528|  2.59k|        int alreadyAdjustedKSubsequence = 0;
  529|       |
  530|       |        // force rotation out of missing k-axes sub-sequence
  531|  2.59k|        if (_h3LeadingNonZeroDigit(current) == K_AXES_DIGIT) {
  ------------------
  |  Branch (531:13): [True: 298, False: 2.29k]
  ------------------
  532|    298|            if (oldBaseCell != newBaseCell) {
  ------------------
  |  Branch (532:17): [True: 115, False: 183]
  ------------------
  533|       |                // in this case, we traversed into the deleted
  534|       |                // k subsequence of a pentagon base cell.
  535|       |                // We need to rotate out of that case depending
  536|       |                // on how we got here.
  537|       |                // check for a cw/ccw offset face; default is ccw
  538|       |
  539|    115|                if (ALWAYS(_baseCellIsCwOffset(
  ------------------
  |  |  118|    115|#define ALWAYS(X) ((X) ? 1 : (assert(0), 0))
  |  |  ------------------
  |  |  |  Branch (118:19): [True: 115, False: 0]
  |  |  |  Branch (118:20): [True: 115, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (539:21): [Folded, False: 0]
  |  Branch (539:21): [Folded, False: 0]
  ------------------
  540|    115|                        newBaseCell,
  541|    115|                        baseCellData[oldBaseCell].homeFijk.face))) {
  542|    115|                    current = _h3Rotate60cw(current);
  543|    115|                } else {
  544|       |                    // See cwOffsetPent in testGridDisk.c for why this is
  545|       |                    // unreachable.
  546|      0|                    current = _h3Rotate60ccw(current);
  547|      0|                }
  548|    115|                alreadyAdjustedKSubsequence = 1;
  549|    183|            } else {
  550|       |                // In this case, we traversed into the deleted
  551|       |                // k subsequence from within the same pentagon
  552|       |                // base cell.
  553|    183|                if (oldLeadingDigit == CENTER_DIGIT) {
  ------------------
  |  Branch (553:21): [True: 0, False: 183]
  ------------------
  554|       |                    // Undefined: the k direction is deleted from here
  555|      0|                    return E_PENTAGON;
  556|    183|                } else if (oldLeadingDigit == JK_AXES_DIGIT) {
  ------------------
  |  Branch (556:28): [True: 55, False: 128]
  ------------------
  557|       |                    // Rotate out of the deleted k subsequence
  558|       |                    // We also need an additional change to the direction we're
  559|       |                    // moving in
  560|     55|                    current = _h3Rotate60ccw(current);
  561|     55|                    *rotations = *rotations + 1;
  562|    128|                } else if (oldLeadingDigit == IK_AXES_DIGIT) {
  ------------------
  |  Branch (562:28): [True: 96, False: 32]
  ------------------
  563|       |                    // Rotate out of the deleted k subsequence
  564|       |                    // We also need an additional change to the direction we're
  565|       |                    // moving in
  566|     96|                    current = _h3Rotate60cw(current);
  567|     96|                    *rotations = *rotations + 5;
  568|     96|                } else {
  569|       |                    // Could occur on invalid inputs that were already within
  570|       |                    // the deleted k subsequence
  571|     32|                    return E_FAILED;
  572|     32|                }
  573|    183|            }
  574|    298|        }
  575|       |
  576|  3.40k|        for (int i = 0; i < newRotations; i++)
  ------------------
  |  Branch (576:25): [True: 840, False: 2.56k]
  ------------------
  577|    840|            current = _h3RotatePent60ccw(current);
  578|       |
  579|       |        // Account for differing orientation of the base cells (this edge
  580|       |        // might not follow properties of some other edges.)
  581|  2.56k|        if (oldBaseCell != newBaseCell) {
  ------------------
  |  Branch (581:13): [True: 452, False: 2.11k]
  ------------------
  582|    452|            if (_isBaseCellPolarPentagon(newBaseCell)) {
  ------------------
  |  Branch (582:17): [True: 200, False: 252]
  ------------------
  583|       |                // 'polar' base cells behave differently because they have all
  584|       |                // i neighbors.
  585|    200|                if (oldBaseCell != 118 && oldBaseCell != 8 &&
  ------------------
  |  Branch (585:21): [True: 179, False: 21]
  |  Branch (585:43): [True: 160, False: 19]
  ------------------
  586|    160|                    _h3LeadingNonZeroDigit(current) != JK_AXES_DIGIT) {
  ------------------
  |  Branch (586:21): [True: 133, False: 27]
  ------------------
  587|    133|                    *rotations = *rotations + 1;
  588|    133|                }
  589|    252|            } else if (_h3LeadingNonZeroDigit(current) == IK_AXES_DIGIT &&
  ------------------
  |  Branch (589:24): [True: 113, False: 139]
  ------------------
  590|    113|                       !alreadyAdjustedKSubsequence) {
  ------------------
  |  Branch (590:24): [True: 41, False: 72]
  ------------------
  591|       |                // account for distortion introduced to the 5 neighbor by the
  592|       |                // deleted k subsequence.
  593|     41|                *rotations = *rotations + 1;
  594|     41|            }
  595|    452|        }
  596|  2.89k|    } else {
  597|  4.77k|        for (int i = 0; i < newRotations; i++)
  ------------------
  |  Branch (597:25): [True: 1.88k, False: 2.89k]
  ------------------
  598|  1.88k|            current = _h3Rotate60ccw(current);
  599|  2.89k|    }
  600|       |
  601|  5.45k|    *rotations = (*rotations + newRotations) % 6;
  602|  5.45k|    *out = current;
  603|       |
  604|  5.45k|    return E_SUCCESS;
  605|  5.48k|}
directionForNeighbor:
  615|    141|Direction directionForNeighbor(H3Index origin, H3Index destination) {
  616|    141|    bool isPent = H3_EXPORT(isPentagon)(origin);
  ------------------
  |  |   36|    141|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    141|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    141|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  617|       |    // Checks each neighbor, in order, to determine which direction the
  618|       |    // destination neighbor is located. Skips CENTER_DIGIT since that
  619|       |    // would be the origin; skips deleted K direction for pentagons.
  620|    141|    for (Direction direction = isPent ? J_AXES_DIGIT : K_AXES_DIGIT;
  ------------------
  |  Branch (620:32): [True: 141, False: 0]
  ------------------
  621|    563|         direction < NUM_DIGITS; direction++) {
  ------------------
  |  Branch (621:10): [True: 543, False: 20]
  ------------------
  622|    543|        H3Index neighbor;
  623|    543|        int rotations = 0;
  624|    543|        H3Error neighborError =
  625|    543|            h3NeighborRotations(origin, direction, &rotations, &neighbor);
  626|    543|        if (!neighborError && neighbor == destination) {
  ------------------
  |  Branch (626:13): [True: 543, False: 0]
  |  Branch (626:31): [True: 121, False: 422]
  ------------------
  627|    121|            return direction;
  628|    121|        }
  629|    543|    }
  630|     20|    return INVALID_DIGIT;
  631|    141|}

_isBaseCellPentagon:
  824|  52.2k|int _isBaseCellPentagon(int baseCell) {
  825|  52.2k|    if (baseCell < 0 || baseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |   81|  52.2k|#define NUM_BASE_CELLS 122
  ------------------
  |  Branch (825:9): [True: 0, False: 52.2k]
  |  Branch (825:25): [True: 42, False: 52.1k]
  ------------------
  826|       |        // Base cells less than zero can not be represented in an index
  827|     42|        return false;
  828|     42|    }
  829|  52.1k|    return baseCellData[baseCell].isPentagon;
  830|  52.2k|}
_isBaseCellPolarPentagon:
  834|  2.75k|bool _isBaseCellPolarPentagon(int baseCell) {
  835|  2.75k|    return baseCell == 4 || baseCell == 117;
  ------------------
  |  Branch (835:12): [True: 554, False: 2.19k]
  |  Branch (835:29): [True: 427, False: 1.77k]
  ------------------
  836|  2.75k|}
_baseCellToFaceIjk:
  866|  7.12k|void _baseCellToFaceIjk(int baseCell, FaceIJK *h) {
  867|  7.12k|    *h = baseCellData[baseCell].homeFijk;
  868|  7.12k|}
_baseCellToCCWrot60:
  877|  7.12k|int _baseCellToCCWrot60(int baseCell, int face) {
  878|  7.12k|    if (face < 0 || face >= NUM_ICOSA_FACES) return INVALID_ROTATIONS;
  ------------------
  |  |   79|  7.12k|#define NUM_ICOSA_FACES 20
  ------------------
                  if (face < 0 || face >= NUM_ICOSA_FACES) return INVALID_ROTATIONS;
  ------------------
  |  |   49|      0|#define INVALID_ROTATIONS -1
  ------------------
  |  Branch (878:9): [True: 0, False: 7.12k]
  |  Branch (878:21): [True: 0, False: 7.12k]
  ------------------
  879|  11.6k|    for (int i = 0; i < 3; i++) {
  ------------------
  |  Branch (879:21): [True: 11.6k, False: 0]
  ------------------
  880|  29.0k|        for (int j = 0; j < 3; j++) {
  ------------------
  |  Branch (880:25): [True: 24.4k, False: 4.56k]
  ------------------
  881|  79.4k|            for (int k = 0; k < 3; k++) {
  ------------------
  |  Branch (881:29): [True: 62.0k, False: 17.3k]
  ------------------
  882|  62.0k|                if (faceIjkBaseCells[face][i][j][k].baseCell == baseCell) {
  ------------------
  |  Branch (882:21): [True: 7.12k, False: 54.9k]
  ------------------
  883|  7.12k|                    return faceIjkBaseCells[face][i][j][k].ccwRot60;
  884|  7.12k|                }
  885|  62.0k|            }
  886|  24.4k|        }
  887|  11.6k|    }
  888|      0|    return INVALID_ROTATIONS;
  ------------------
  |  |   49|      0|#define INVALID_ROTATIONS -1
  ------------------
  889|  7.12k|}
_baseCellIsCwOffset:
  893|    115|bool _baseCellIsCwOffset(int baseCell, int testFace) {
  894|    115|    return baseCellData[baseCell].cwOffsetPent[0] == testFace ||
  ------------------
  |  Branch (894:12): [True: 33, False: 82]
  ------------------
  895|     82|           baseCellData[baseCell].cwOffsetPent[1] == testFace;
  ------------------
  |  Branch (895:12): [True: 82, False: 0]
  ------------------
  896|    115|}

_faceIjkPentToCellBoundary:
  532|     21|                                int length, CellBoundary *g) {
  533|     21|    int adjRes = res;
  534|     21|    FaceIJK centerIJK = *h;
  535|     21|    FaceIJK fijkVerts[NUM_PENT_VERTS];
  536|     21|    _faceIjkPentToVerts(&centerIJK, &adjRes, fijkVerts);
  537|       |
  538|       |    // If we're returning the entire loop, we need one more iteration in case
  539|       |    // of a distortion vertex on the last edge
  540|     21|    int additionalIteration = length == NUM_PENT_VERTS ? 1 : 0;
  ------------------
  |  |   85|     21|#define NUM_PENT_VERTS 5
  ------------------
  |  Branch (540:31): [True: 0, False: 21]
  ------------------
  541|       |
  542|       |    // convert each vertex to lat/lng
  543|       |    // adjust the face of each vertex as appropriate and introduce
  544|       |    // edge-crossing vertices as needed
  545|     21|    g->numVerts = 0;
  546|     21|    FaceIJK lastFijk = {0};
  547|     42|    for (int vert = start; vert < start + length + additionalIteration;
  ------------------
  |  Branch (547:28): [True: 21, False: 21]
  ------------------
  548|     21|         vert++) {
  549|     21|        int v = vert % NUM_PENT_VERTS;
  ------------------
  |  |   85|     21|#define NUM_PENT_VERTS 5
  ------------------
  550|       |
  551|     21|        FaceIJK fijk = fijkVerts[v];
  552|       |
  553|     21|        _adjustPentVertOverage(&fijk, adjRes);
  554|       |
  555|       |        // all Class III pentagon edges cross icosa edges
  556|       |        // note that Class II pentagons have vertices on the edge,
  557|       |        // not edge intersections
  558|     21|        if (isResolutionClassIII(res) && vert > start) {
  ------------------
  |  Branch (558:13): [True: 9, False: 12]
  |  Branch (558:42): [True: 0, False: 9]
  ------------------
  559|       |            // find hex2d of the two vertexes on the last face
  560|       |
  561|      0|            FaceIJK tmpFijk = fijk;
  562|       |
  563|      0|            Vec2d orig2d0;
  564|      0|            _ijkToHex2d(&lastFijk.coord, &orig2d0);
  565|       |
  566|      0|            int currentToLastDir = adjacentFaceDir[tmpFijk.face][lastFijk.face];
  567|       |
  568|      0|            const FaceOrientIJK *fijkOrient =
  569|      0|                &faceNeighbors[tmpFijk.face][currentToLastDir];
  570|       |
  571|      0|            tmpFijk.face = fijkOrient->face;
  572|      0|            CoordIJK *ijk = &tmpFijk.coord;
  573|       |
  574|       |            // rotate and translate for adjacent face
  575|      0|            for (int i = 0; i < fijkOrient->ccwRot60; i++) _ijkRotate60ccw(ijk);
  ------------------
  |  Branch (575:29): [True: 0, False: 0]
  ------------------
  576|       |
  577|      0|            CoordIJK transVec = fijkOrient->translate;
  578|      0|            _ijkScale(&transVec, unitScaleByCIIres[adjRes] * 3);
  579|      0|            _ijkAdd(ijk, &transVec, ijk);
  580|      0|            _ijkNormalize(ijk);
  581|       |
  582|      0|            Vec2d orig2d1;
  583|      0|            _ijkToHex2d(ijk, &orig2d1);
  584|       |
  585|       |            // find the appropriate icosa face edge vertexes
  586|      0|            int maxDim = maxDimByCIIres[adjRes];
  587|      0|            Vec2d v0 = {3.0 * maxDim, 0.0};
  588|      0|            Vec2d v1 = {-1.5 * maxDim, 3.0 * M_SQRT3_2 * maxDim};
  ------------------
  |  |   44|      0|#define M_SQRT3_2 0.8660254037844386467637231707529361834714
  ------------------
  589|      0|            Vec2d v2 = {-1.5 * maxDim, -3.0 * M_SQRT3_2 * maxDim};
  ------------------
  |  |   44|      0|#define M_SQRT3_2 0.8660254037844386467637231707529361834714
  ------------------
  590|       |
  591|      0|            Vec2d *edge0;
  592|      0|            Vec2d *edge1;
  593|      0|            switch (adjacentFaceDir[tmpFijk.face][fijk.face]) {
  594|      0|                case IJ:
  ------------------
  |  |   53|      0|#define IJ 1
  ------------------
  |  Branch (594:17): [True: 0, False: 0]
  ------------------
  595|      0|                    edge0 = &v0;
  596|      0|                    edge1 = &v1;
  597|      0|                    break;
  598|      0|                case JK:
  ------------------
  |  |   57|      0|#define JK 3
  ------------------
  |  Branch (598:17): [True: 0, False: 0]
  ------------------
  599|      0|                    edge0 = &v1;
  600|      0|                    edge1 = &v2;
  601|      0|                    break;
  602|      0|                case KI:
  ------------------
  |  |   55|      0|#define KI 2
  ------------------
  |  Branch (602:17): [True: 0, False: 0]
  ------------------
  603|      0|                default:
  ------------------
  |  Branch (603:17): [True: 0, False: 0]
  ------------------
  604|      0|                    assert(adjacentFaceDir[tmpFijk.face][fijk.face] == KI);
  ------------------
  |  Branch (604:21): [True: 0, False: 0]
  |  Branch (604:21): [True: 0, False: 0]
  ------------------
  605|      0|                    edge0 = &v2;
  606|      0|                    edge1 = &v0;
  607|      0|                    break;
  608|      0|            }
  609|       |
  610|       |            // find the intersection and add the lat/lng point to the result
  611|      0|            Vec2d inter;
  612|      0|            _v2dIntersect(&orig2d0, &orig2d1, edge0, edge1, &inter);
  613|      0|            Vec3d v3;
  614|      0|            _hex2dToVec3(&inter, tmpFijk.face, adjRes, 1, &v3);
  615|      0|            g->verts[g->numVerts] = vec3ToLatLng(v3);
  616|      0|            g->numVerts++;
  617|      0|        }
  618|       |
  619|       |        // convert vertex to lat/lng and add to the result
  620|       |        // vert == start + NUM_PENT_VERTS is only used to test for possible
  621|       |        // intersection on last edge
  622|     21|        if (vert < start + NUM_PENT_VERTS) {
  ------------------
  |  |   85|     21|#define NUM_PENT_VERTS 5
  ------------------
  |  Branch (622:13): [True: 21, False: 0]
  ------------------
  623|     21|            Vec2d vec;
  624|     21|            _ijkToHex2d(&fijk.coord, &vec);
  625|     21|            Vec3d v3;
  626|     21|            _hex2dToVec3(&vec, fijk.face, adjRes, 1, &v3);
  627|     21|            g->verts[g->numVerts] = vec3ToLatLng(v3);
  628|     21|            g->numVerts++;
  629|     21|        }
  630|       |
  631|     21|        lastFijk = fijk;
  632|     21|    }
  633|     21|}
_faceIjkPentToVerts:
  642|     21|void _faceIjkPentToVerts(FaceIJK *fijk, int *res, FaceIJK *fijkVerts) {
  643|       |    // the vertexes of an origin-centered pentagon in a Class II resolution on a
  644|       |    // substrate grid with aperture sequence 33r. The aperture 3 gets us the
  645|       |    // vertices, and the 3r gets us back to Class II.
  646|       |    // vertices listed ccw from the i-axes
  647|     21|    CoordIJK vertsCII[NUM_PENT_VERTS] = {
  648|     21|        {2, 1, 0},  // 0
  649|     21|        {1, 2, 0},  // 1
  650|     21|        {0, 2, 1},  // 2
  651|     21|        {0, 1, 2},  // 3
  652|     21|        {1, 0, 2},  // 4
  653|     21|    };
  654|       |
  655|       |    // the vertexes of an origin-centered pentagon in a Class III resolution on
  656|       |    // a substrate grid with aperture sequence 33r7r. The aperture 3 gets us the
  657|       |    // vertices, and the 3r7r gets us to Class II. vertices listed ccw from the
  658|       |    // i-axes
  659|     21|    CoordIJK vertsCIII[NUM_PENT_VERTS] = {
  660|     21|        {5, 4, 0},  // 0
  661|     21|        {1, 5, 0},  // 1
  662|     21|        {0, 5, 4},  // 2
  663|     21|        {0, 1, 5},  // 3
  664|     21|        {4, 0, 5},  // 4
  665|     21|    };
  666|       |
  667|       |    // get the correct set of substrate vertices for this resolution
  668|     21|    CoordIJK *verts;
  669|     21|    if (isResolutionClassIII(*res))
  ------------------
  |  Branch (669:9): [True: 9, False: 12]
  ------------------
  670|      9|        verts = vertsCIII;
  671|     12|    else
  672|     12|        verts = vertsCII;
  673|       |
  674|       |    // adjust the center point to be in an aperture 33r substrate grid
  675|       |    // these should be composed for speed
  676|     21|    _downAp3(&fijk->coord);
  677|     21|    _downAp3r(&fijk->coord);
  678|       |
  679|       |    // if res is Class III we need to add a cw aperture 7 to get to
  680|       |    // icosahedral Class II
  681|     21|    if (isResolutionClassIII(*res)) {
  ------------------
  |  Branch (681:9): [True: 9, False: 12]
  ------------------
  682|      9|        _downAp7r(&fijk->coord);
  683|      9|        *res += 1;
  684|      9|    }
  685|       |
  686|       |    // The center point is now in the same substrate grid as the origin
  687|       |    // cell vertices. Add the center point substate coordinates
  688|       |    // to each vertex to translate the vertices to that cell.
  689|    126|    for (int v = 0; v < NUM_PENT_VERTS; v++) {
  ------------------
  |  |   85|    126|#define NUM_PENT_VERTS 5
  ------------------
  |  Branch (689:21): [True: 105, False: 21]
  ------------------
  690|    105|        fijkVerts[v].face = fijk->face;
  691|    105|        _ijkAdd(&fijk->coord, &verts[v], &fijkVerts[v].coord);
  692|    105|        _ijkNormalize(&fijkVerts[v].coord);
  693|    105|    }
  694|     21|}
_faceIjkToCellBoundary:
  707|    541|                            CellBoundary *g) {
  708|    541|    int adjRes = res;
  709|    541|    FaceIJK centerIJK = *h;
  710|    541|    FaceIJK fijkVerts[NUM_HEX_VERTS];
  711|    541|    _faceIjkToVerts(&centerIJK, &adjRes, fijkVerts);
  712|       |
  713|       |    // If we're returning the entire loop, we need one more iteration in case
  714|       |    // of a distortion vertex on the last edge
  715|    541|    int additionalIteration = length == NUM_HEX_VERTS ? 1 : 0;
  ------------------
  |  |   83|    541|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (715:31): [True: 0, False: 541]
  ------------------
  716|       |
  717|       |    // convert each vertex to lat/lng
  718|       |    // adjust the face of each vertex as appropriate and introduce
  719|       |    // edge-crossing vertices as needed
  720|    541|    g->numVerts = 0;
  721|    541|    int lastFace = -1;
  722|    541|    Overage lastOverage = NO_OVERAGE;
  723|  1.08k|    for (int vert = start; vert < start + length + additionalIteration;
  ------------------
  |  Branch (723:28): [True: 541, False: 541]
  ------------------
  724|    541|         vert++) {
  725|    541|        int v = vert % NUM_HEX_VERTS;
  ------------------
  |  |   83|    541|#define NUM_HEX_VERTS 6
  ------------------
  726|       |
  727|    541|        FaceIJK fijk = fijkVerts[v];
  728|       |
  729|    541|        const int pentLeading4 = 0;
  730|    541|        Overage overage = _adjustOverageClassII(&fijk, adjRes, pentLeading4, 1);
  731|       |
  732|       |        /*
  733|       |        Check for edge-crossing. Each face of the underlying icosahedron is a
  734|       |        different projection plane. So if an edge of the hexagon crosses an
  735|       |        icosahedron edge, an additional vertex must be introduced at that
  736|       |        intersection point. Then each half of the cell edge can be projected
  737|       |        to geographic coordinates using the appropriate icosahedron face
  738|       |        projection. Note that Class II cell edges have vertices on the face
  739|       |        edge, with no edge line intersections.
  740|       |        */
  741|    541|        if (isResolutionClassIII(res) && vert > start &&
  ------------------
  |  Branch (741:13): [True: 402, False: 139]
  |  Branch (741:42): [True: 0, False: 402]
  ------------------
  742|      0|            fijk.face != lastFace && lastOverage != FACE_EDGE) {
  ------------------
  |  Branch (742:13): [True: 0, False: 0]
  |  Branch (742:38): [True: 0, False: 0]
  ------------------
  743|       |            // find hex2d of the two vertexes on original face
  744|      0|            int lastV = (v + 5) % NUM_HEX_VERTS;
  ------------------
  |  |   83|      0|#define NUM_HEX_VERTS 6
  ------------------
  745|      0|            Vec2d orig2d0;
  746|      0|            _ijkToHex2d(&fijkVerts[lastV].coord, &orig2d0);
  747|       |
  748|      0|            Vec2d orig2d1;
  749|      0|            _ijkToHex2d(&fijkVerts[v].coord, &orig2d1);
  750|       |
  751|       |            // find the appropriate icosa face edge vertexes
  752|      0|            int maxDim = maxDimByCIIres[adjRes];
  753|      0|            Vec2d v0 = {3.0 * maxDim, 0.0};
  754|      0|            Vec2d v1 = {-1.5 * maxDim, 3.0 * M_SQRT3_2 * maxDim};
  ------------------
  |  |   44|      0|#define M_SQRT3_2 0.8660254037844386467637231707529361834714
  ------------------
  755|      0|            Vec2d v2 = {-1.5 * maxDim, -3.0 * M_SQRT3_2 * maxDim};
  ------------------
  |  |   44|      0|#define M_SQRT3_2 0.8660254037844386467637231707529361834714
  ------------------
  756|       |
  757|      0|            int face2 = ((lastFace == centerIJK.face) ? fijk.face : lastFace);
  ------------------
  |  Branch (757:26): [True: 0, False: 0]
  ------------------
  758|      0|            Vec2d *edge0;
  759|      0|            Vec2d *edge1;
  760|      0|            switch (adjacentFaceDir[centerIJK.face][face2]) {
  761|      0|                case IJ:
  ------------------
  |  |   53|      0|#define IJ 1
  ------------------
  |  Branch (761:17): [True: 0, False: 0]
  ------------------
  762|      0|                    edge0 = &v0;
  763|      0|                    edge1 = &v1;
  764|      0|                    break;
  765|      0|                case JK:
  ------------------
  |  |   57|      0|#define JK 3
  ------------------
  |  Branch (765:17): [True: 0, False: 0]
  ------------------
  766|      0|                    edge0 = &v1;
  767|      0|                    edge1 = &v2;
  768|      0|                    break;
  769|       |                // case KI:
  770|      0|                default:
  ------------------
  |  Branch (770:17): [True: 0, False: 0]
  ------------------
  771|      0|                    assert(adjacentFaceDir[centerIJK.face][face2] == KI);
  ------------------
  |  Branch (771:21): [True: 0, False: 0]
  |  Branch (771:21): [True: 0, False: 0]
  ------------------
  772|      0|                    edge0 = &v2;
  773|      0|                    edge1 = &v0;
  774|      0|                    break;
  775|      0|            }
  776|       |
  777|       |            // find the intersection and add the lat/lng point to the result
  778|      0|            Vec2d inter;
  779|      0|            _v2dIntersect(&orig2d0, &orig2d1, edge0, edge1, &inter);
  780|       |            /*
  781|       |            If a point of intersection occurs at a hexagon vertex, then each
  782|       |            adjacent hexagon edge will lie completely on a single icosahedron
  783|       |            face, and no additional vertex is required.
  784|       |            */
  785|      0|            bool isIntersectionAtVertex = _v2dAlmostEquals(&orig2d0, &inter) ||
  ------------------
  |  Branch (785:43): [True: 0, False: 0]
  ------------------
  786|      0|                                          _v2dAlmostEquals(&orig2d1, &inter);
  ------------------
  |  Branch (786:43): [True: 0, False: 0]
  ------------------
  787|      0|            if (!isIntersectionAtVertex) {
  ------------------
  |  Branch (787:17): [True: 0, False: 0]
  ------------------
  788|      0|                Vec3d v3;
  789|      0|                _hex2dToVec3(&inter, centerIJK.face, adjRes, 1, &v3);
  790|      0|                g->verts[g->numVerts] = vec3ToLatLng(v3);
  791|      0|                g->numVerts++;
  792|      0|            }
  793|      0|        }
  794|       |
  795|       |        // convert vertex to lat/lng and add to the result
  796|       |        // vert == start + NUM_HEX_VERTS is only used to test for possible
  797|       |        // intersection on last edge
  798|    541|        if (vert < start + NUM_HEX_VERTS) {
  ------------------
  |  |   83|    541|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (798:13): [True: 541, False: 0]
  ------------------
  799|    541|            Vec2d vec;
  800|    541|            _ijkToHex2d(&fijk.coord, &vec);
  801|    541|            Vec3d v3;
  802|    541|            _hex2dToVec3(&vec, fijk.face, adjRes, 1, &v3);
  803|    541|            g->verts[g->numVerts] = vec3ToLatLng(v3);
  804|    541|            g->numVerts++;
  805|    541|        }
  806|       |
  807|    541|        lastFace = fijk.face;
  808|    541|        lastOverage = overage;
  809|    541|    }
  810|    541|}
_faceIjkToVerts:
  819|    541|void _faceIjkToVerts(FaceIJK *fijk, int *res, FaceIJK *fijkVerts) {
  820|       |    // the vertexes of an origin-centered cell in a Class II resolution on a
  821|       |    // substrate grid with aperture sequence 33r. The aperture 3 gets us the
  822|       |    // vertices, and the 3r gets us back to Class II.
  823|       |    // vertices listed ccw from the i-axes
  824|    541|    CoordIJK vertsCII[NUM_HEX_VERTS] = {
  825|    541|        {2, 1, 0},  // 0
  826|    541|        {1, 2, 0},  // 1
  827|    541|        {0, 2, 1},  // 2
  828|    541|        {0, 1, 2},  // 3
  829|    541|        {1, 0, 2},  // 4
  830|    541|        {2, 0, 1}   // 5
  831|    541|    };
  832|       |
  833|       |    // the vertexes of an origin-centered cell in a Class III resolution on a
  834|       |    // substrate grid with aperture sequence 33r7r. The aperture 3 gets us the
  835|       |    // vertices, and the 3r7r gets us to Class II.
  836|       |    // vertices listed ccw from the i-axes
  837|    541|    CoordIJK vertsCIII[NUM_HEX_VERTS] = {
  838|    541|        {5, 4, 0},  // 0
  839|    541|        {1, 5, 0},  // 1
  840|    541|        {0, 5, 4},  // 2
  841|    541|        {0, 1, 5},  // 3
  842|    541|        {4, 0, 5},  // 4
  843|    541|        {5, 0, 1}   // 5
  844|    541|    };
  845|       |
  846|       |    // get the correct set of substrate vertices for this resolution
  847|    541|    CoordIJK *verts;
  848|    541|    if (isResolutionClassIII(*res))
  ------------------
  |  Branch (848:9): [True: 402, False: 139]
  ------------------
  849|    402|        verts = vertsCIII;
  850|    139|    else
  851|    139|        verts = vertsCII;
  852|       |
  853|       |    // adjust the center point to be in an aperture 33r substrate grid
  854|       |    // these should be composed for speed
  855|    541|    _downAp3(&fijk->coord);
  856|    541|    _downAp3r(&fijk->coord);
  857|       |
  858|       |    // if res is Class III we need to add a cw aperture 7 to get to
  859|       |    // icosahedral Class II
  860|    541|    if (isResolutionClassIII(*res)) {
  ------------------
  |  Branch (860:9): [True: 402, False: 139]
  ------------------
  861|    402|        _downAp7r(&fijk->coord);
  862|    402|        *res += 1;
  863|    402|    }
  864|       |
  865|       |    // The center point is now in the same substrate grid as the origin
  866|       |    // cell vertices. Add the center point substate coordinates
  867|       |    // to each vertex to translate the vertices to that cell.
  868|  3.78k|    for (int v = 0; v < NUM_HEX_VERTS; v++) {
  ------------------
  |  |   83|  3.78k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (868:21): [True: 3.24k, False: 541]
  ------------------
  869|  3.24k|        fijkVerts[v].face = fijk->face;
  870|  3.24k|        _ijkAdd(&fijk->coord, &verts[v], &fijkVerts[v].coord);
  871|  3.24k|        _ijkNormalize(&fijkVerts[v].coord);
  872|  3.24k|    }
  873|    541|}
_adjustOverageClassII:
  888|  11.5k|                              int substrate) {
  889|  11.5k|    Overage overage = NO_OVERAGE;
  890|       |
  891|  11.5k|    CoordIJK *ijk = &fijk->coord;
  892|       |
  893|       |    // get the maximum dimension value; scale if a substrate grid
  894|  11.5k|    int maxDim = maxDimByCIIres[res];
  895|  11.5k|    if (substrate) maxDim *= 3;
  ------------------
  |  Branch (895:9): [True: 581, False: 10.9k]
  ------------------
  896|       |
  897|       |    // check for overage
  898|  11.5k|    if (substrate && ijk->i + ijk->j + ijk->k == maxDim)  // on edge
  ------------------
  |  Branch (898:9): [True: 581, False: 10.9k]
  |  Branch (898:22): [True: 66, False: 515]
  ------------------
  899|     66|        overage = FACE_EDGE;
  900|  11.5k|    else if (ijk->i + ijk->j + ijk->k > maxDim)  // overage
  ------------------
  |  Branch (900:14): [True: 5.33k, False: 6.17k]
  ------------------
  901|  5.33k|    {
  902|  5.33k|        overage = NEW_FACE;
  903|       |
  904|  5.33k|        const FaceOrientIJK *fijkOrient;
  905|  5.33k|        if (ijk->k > 0) {
  ------------------
  |  Branch (905:13): [True: 3.68k, False: 1.65k]
  ------------------
  906|  3.68k|            if (ijk->j > 0)  // jk "quadrant"
  ------------------
  |  Branch (906:17): [True: 1.18k, False: 2.50k]
  ------------------
  907|  1.18k|                fijkOrient = &faceNeighbors[fijk->face][JK];
  ------------------
  |  |   57|  1.18k|#define JK 3
  ------------------
  908|  2.50k|            else  // ik "quadrant"
  909|  2.50k|            {
  910|  2.50k|                fijkOrient = &faceNeighbors[fijk->face][KI];
  ------------------
  |  |   55|  2.50k|#define KI 2
  ------------------
  911|       |
  912|       |                // adjust for the pentagonal missing sequence
  913|  2.50k|                if (pentLeading4) {
  ------------------
  |  Branch (913:21): [True: 525, False: 1.97k]
  ------------------
  914|       |                    // translate origin to center of pentagon
  915|    525|                    CoordIJK origin;
  916|    525|                    _setIJK(&origin, maxDim, 0, 0);
  917|    525|                    CoordIJK tmp;
  918|    525|                    _ijkSub(ijk, &origin, &tmp);
  919|       |                    // rotate to adjust for the missing sequence
  920|    525|                    _ijkRotate60cw(&tmp);
  921|       |                    // translate the origin back to the center of the triangle
  922|    525|                    _ijkAdd(&tmp, &origin, ijk);
  923|    525|                }
  924|  2.50k|            }
  925|  3.68k|        } else  // ij "quadrant"
  926|  1.65k|            fijkOrient = &faceNeighbors[fijk->face][IJ];
  ------------------
  |  |   53|  1.65k|#define IJ 1
  ------------------
  927|       |
  928|  5.33k|        fijk->face = fijkOrient->face;
  929|       |
  930|       |        // rotate and translate for adjacent face
  931|  21.5k|        for (int i = 0; i < fijkOrient->ccwRot60; i++) _ijkRotate60ccw(ijk);
  ------------------
  |  Branch (931:25): [True: 16.2k, False: 5.33k]
  ------------------
  932|       |
  933|  5.33k|        CoordIJK transVec = fijkOrient->translate;
  934|  5.33k|        int unitScale = unitScaleByCIIres[res];
  935|  5.33k|        if (substrate) unitScale *= 3;
  ------------------
  |  Branch (935:13): [True: 55, False: 5.28k]
  ------------------
  936|  5.33k|        _ijkScale(&transVec, unitScale);
  937|  5.33k|        _ijkAdd(ijk, &transVec, ijk);
  938|  5.33k|        _ijkNormalize(ijk);
  939|       |
  940|       |        // overage points on pentagon boundaries can end up on edges
  941|  5.33k|        if (substrate && ijk->i + ijk->j + ijk->k == maxDim)  // on edge
  ------------------
  |  Branch (941:13): [True: 55, False: 5.28k]
  |  Branch (941:26): [True: 10, False: 45]
  ------------------
  942|     10|            overage = FACE_EDGE;
  943|  5.33k|    }
  944|       |
  945|  11.5k|    return overage;
  946|  11.5k|}
_adjustPentVertOverage:
  956|     21|Overage _adjustPentVertOverage(FaceIJK *fijk, int res) {
  957|     21|    int pentLeading4 = 0;
  958|     21|    Overage overage;
  959|     40|    do {
  960|     40|        overage = _adjustOverageClassII(fijk, res, pentLeading4, 1);
  961|     40|    } while (overage == NEW_FACE);
  ------------------
  |  Branch (961:14): [True: 19, False: 21]
  ------------------
  962|     21|    return overage;
  963|     21|}
faceijk.c:_vec3TangentBasis:
  375|    562|static inline void _vec3TangentBasis(Vec3d p, Vec3d *north, Vec3d *east) {
  376|    562|    Vec3d northPole = {0.0, 0.0, 1.0};
  377|    562|    *north = vec3LinComb(1.0, northPole, -vec3Dot(northPole, p), p);
  378|    562|    vec3Normalize(north);
  379|    562|    *east = vec3Cross(*north, p);
  380|    562|}
faceijk.c:_hex2dToVec3:
  459|    562|                         Vec3d *v3) {
  460|       |    // calculate (r, theta) in hex2d
  461|    562|    double r = _v2dMag(v);
  462|       |
  463|    562|    if (r < EPSILON) {
  ------------------
  |  |   42|    562|#define EPSILON 0.0000000000000001
  ------------------
  |  Branch (463:9): [True: 0, False: 562]
  ------------------
  464|      0|        *v3 = faceCenterPoint[face];
  465|      0|        return;
  466|      0|    }
  467|       |
  468|    562|    double theta = atan2(v->y, v->x);
  469|       |
  470|       |    // scale for current resolution length u
  471|  6.32k|    for (int i = 0; i < res; i++) r *= M_RSQRT7;
  ------------------
  |  |   37|  6.32k|#define M_RSQRT7 0.37796447300922722721451653623418006081576
  ------------------
  |  Branch (471:21): [True: 5.76k, False: 562]
  ------------------
  472|       |
  473|       |    // scale accordingly if this is a substrate grid
  474|    562|    if (substrate) {
  ------------------
  |  Branch (474:9): [True: 562, False: 0]
  ------------------
  475|    562|        r *= M_ONETHIRD;
  ------------------
  |  |   51|    562|#define M_ONETHIRD 0.333333333333333333333333333333333333333
  ------------------
  476|       |        // Never occurs because every case where this function is called with
  477|       |        // substrate=1, the res has been adjusted by _faceIjkPentToVerts, which
  478|       |        // adjusts the res by +1, making it no longer Class III.
  479|    562|        if (NEVER(isResolutionClassIII(res))) {
  ------------------
  |  |  119|    562|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 562]
  |  |  |  Branch (119:19): [True: 0, False: 562]
  |  |  ------------------
  ------------------
  |  Branch (479:13): [Folded, False: 0]
  |  Branch (479:13): [Folded, False: 0]
  ------------------
  480|      0|            r *= M_RSQRT7;
  ------------------
  |  |   37|      0|#define M_RSQRT7 0.37796447300922722721451653623418006081576
  ------------------
  481|      0|        }
  482|    562|    }
  483|       |
  484|    562|    r *= RES0_U_GNOMONIC;
  ------------------
  |  |   72|    562|#define RES0_U_GNOMONIC 0.38196601125010500003
  ------------------
  485|       |
  486|       |    // perform inverse gnomonic scaling of r
  487|    562|    r = atan(r);
  488|       |
  489|       |    // adjust theta for Class III
  490|       |    // if a substrate grid, then it's already been adjusted for Class III
  491|    562|    if (!substrate && isResolutionClassIII(res))
  ------------------
  |  Branch (491:9): [True: 0, False: 562]
  |  Branch (491:23): [True: 0, False: 0]
  ------------------
  492|      0|        theta = _posAngleRads(theta + M_AP7_ROT_RADS);
  ------------------
  |  |   58|      0|#define M_AP7_ROT_RADS 0.333473172251832115336090755351601070065900389
  ------------------
  493|       |
  494|       |    // find theta as an azimuth
  495|    562|    theta = _posAngleRads(faceAxesAzRadsCII[face][0] - theta);
  496|       |
  497|       |    // now find the point at (r,theta) from the face center
  498|    562|    Vec3d northDir, eastDir;
  499|    562|    _vec3TangentBasis(faceCenterPoint[face], &northDir, &eastDir);
  500|       |
  501|    562|    Vec3d dir = vec3LinComb(cos(theta), northDir, sin(theta), eastDir);
  502|       |
  503|    562|    *v3 = vec3LinComb(cos(r), faceCenterPoint[face], sin(r), dir);
  504|    562|    vec3Normalize(v3);
  505|    562|}

getBaseCellNumber:
   98|  7.12k|int H3_EXPORT(getBaseCellNumber)(H3Index h) { return H3_GET_BASE_CELL(h); }
  ------------------
  |  |  118|  7.12k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  7.12k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  7.12k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  7.12k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
isValidCell:
  343|    241|int H3_EXPORT(isValidCell)(H3Index h) {
  344|       |    /*
  345|       |    Look for bit patterns that would disqualify an H3Index from
  346|       |    being valid. If identified, exit early.
  347|       |
  348|       |    For reference the H3 index bit layout:
  349|       |
  350|       |    |   Region   | # bits |
  351|       |    |------------|--------|
  352|       |    | High       |      1 |
  353|       |    | Mode       |      4 |
  354|       |    | Reserved   |      3 |
  355|       |    | Resolution |      4 |
  356|       |    | Base Cell  |      7 |
  357|       |    | Digit 1    |      3 |
  358|       |    | Digit 2    |      3 |
  359|       |    | ...        |    ... |
  360|       |    | Digit 15   |      3 |
  361|       |
  362|       |    Speed benefits come from using bit manipulation instead of loops,
  363|       |    whenever possible.
  364|       |    */
  365|    241|    if (!_hasGoodTopBits(h)) return false;
  ------------------
  |  Branch (365:9): [True: 7, False: 234]
  ------------------
  366|       |
  367|       |    // No need to check resolution; any 4 bits give a valid resolution.
  368|    234|    const int res = H3_GET_RESOLUTION(h);
  ------------------
  |  |  129|    234|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|    234|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|    234|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|    234|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  369|       |
  370|       |    // Get base cell number and check that it is valid.
  371|    234|    const int bc = H3_GET_BASE_CELL(h);
  ------------------
  |  |  118|    234|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|    234|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|    234|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|    234|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  372|    234|    if (bc >= NUM_BASE_CELLS) return false;
  ------------------
  |  |   81|    234|#define NUM_BASE_CELLS 122
  ------------------
  |  Branch (372:9): [True: 2, False: 232]
  ------------------
  373|       |
  374|    232|    if (_hasAny7UptoRes(h, res)) return false;
  ------------------
  |  Branch (374:9): [True: 32, False: 200]
  ------------------
  375|    200|    if (!_hasAll7AfterRes(h, res)) return false;
  ------------------
  |  Branch (375:9): [True: 62, False: 138]
  ------------------
  376|    138|    if (_hasDeletedSubsequence(h, bc)) return false;
  ------------------
  |  Branch (376:9): [True: 8, False: 130]
  ------------------
  377|       |
  378|       |    // If no disqualifications were identified, the index is a valid H3 cell.
  379|    130|    return true;
  380|    138|}
isPentagon:
  845|  14.0k|int H3_EXPORT(isPentagon)(H3Index h) {
  846|  14.0k|    return _isBaseCellPentagon(H3_GET_BASE_CELL(h)) &&
  ------------------
  |  |  118|  14.0k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  14.0k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  14.0k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  14.0k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  |  Branch (846:12): [True: 5.77k, False: 8.29k]
  ------------------
  847|  5.77k|           !_h3LeadingNonZeroDigit(h);
  ------------------
  |  Branch (847:12): [True: 641, False: 5.13k]
  ------------------
  848|  14.0k|}
_h3LeadingNonZeroDigit:
  855|  28.2k|Direction _h3LeadingNonZeroDigit(H3Index h) {
  856|  83.2k|    for (int r = 1; r <= H3_GET_RESOLUTION(h); r++)
  ------------------
  |  |  129|  83.2k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  83.2k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  83.2k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  83.2k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (856:21): [True: 79.8k, False: 3.35k]
  ------------------
  857|  79.8k|        if (H3_GET_INDEX_DIGIT(h, r)) return H3_GET_INDEX_DIGIT(h, r);
  ------------------
  |  |  141|  79.8k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  79.8k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  79.8k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  |  Branch (141:5): [True: 24.8k, False: 54.9k]
  |  |  ------------------
  |  |  142|  79.8k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  79.8k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
                      if (H3_GET_INDEX_DIGIT(h, r)) return H3_GET_INDEX_DIGIT(h, r);
  ------------------
  |  |  141|  24.8k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  24.8k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  24.8k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  24.8k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  24.8k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  858|       |
  859|       |    // if we're here it's all 0's
  860|  3.35k|    return CENTER_DIGIT;
  861|  28.2k|}
_h3RotatePent60ccw:
  867|    840|H3Index _h3RotatePent60ccw(H3Index h) {
  868|       |    // rotate in place; skips any leading 1 digits (k-axis)
  869|       |
  870|    840|    int foundFirstNonZeroDigit = 0;
  871|  6.95k|    for (int r = 1, res = H3_GET_RESOLUTION(h); r <= res; r++) {
  ------------------
  |  |  129|    840|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|    840|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|    840|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|    840|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (871:49): [True: 6.11k, False: 840]
  ------------------
  872|       |        // rotate this digit
  873|  6.11k|        H3_SET_INDEX_DIGIT(h, r, _rotate60ccw(H3_GET_INDEX_DIGIT(h, r)));
  ------------------
  |  |  162|  6.11k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  6.11k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  6.11k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  6.11k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  6.11k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  6.11k|            (((uint64_t)(digit))                                            \
  |  |  165|  6.11k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  6.11k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  6.11k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  ------------------
  874|       |
  875|       |        // look for the first non-zero digit so we
  876|       |        // can adjust for deleted k-axes sequence
  877|       |        // if necessary
  878|  6.11k|        if (!foundFirstNonZeroDigit && H3_GET_INDEX_DIGIT(h, r) != 0) {
  ------------------
  |  |  141|    703|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|    703|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|    703|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|    703|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|    703|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  |  Branch (878:13): [True: 703, False: 5.41k]
  |  Branch (878:40): [True: 703, False: 0]
  ------------------
  879|    703|            foundFirstNonZeroDigit = 1;
  880|       |
  881|       |            // adjust for deleted k-axes sequence
  882|    703|            if (_h3LeadingNonZeroDigit(h) == K_AXES_DIGIT)
  ------------------
  |  Branch (882:17): [True: 245, False: 458]
  ------------------
  883|    245|                h = _h3Rotate60ccw(h);
  884|    703|        }
  885|  6.11k|    }
  886|    840|    return h;
  887|    840|}
_h3Rotate60ccw:
  918|  2.24k|H3Index _h3Rotate60ccw(H3Index h) {
  919|  9.92k|    for (int r = 1, res = H3_GET_RESOLUTION(h); r <= res; r++) {
  ------------------
  |  |  129|  2.24k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  2.24k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  2.24k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  2.24k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (919:49): [True: 7.67k, False: 2.24k]
  ------------------
  920|  7.67k|        Direction oldDigit = H3_GET_INDEX_DIGIT(h, r);
  ------------------
  |  |  141|  7.67k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  7.67k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  7.67k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  7.67k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  7.67k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  921|  7.67k|        H3_SET_INDEX_DIGIT(h, r, _rotate60ccw(oldDigit));
  ------------------
  |  |  162|  7.67k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  7.67k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  7.67k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  7.67k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  7.67k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  7.67k|            (((uint64_t)(digit))                                            \
  |  |  165|  7.67k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  7.67k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  7.67k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  ------------------
  922|  7.67k|    }
  923|       |
  924|  2.24k|    return h;
  925|  2.24k|}
_h3Rotate60cw:
  931|    834|H3Index _h3Rotate60cw(H3Index h) {
  932|  9.91k|    for (int r = 1, res = H3_GET_RESOLUTION(h); r <= res; r++) {
  ------------------
  |  |  129|    834|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|    834|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|    834|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|    834|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (932:49): [True: 9.08k, False: 834]
  ------------------
  933|  9.08k|        H3_SET_INDEX_DIGIT(h, r, _rotate60cw(H3_GET_INDEX_DIGIT(h, r)));
  ------------------
  |  |  162|  9.08k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  9.08k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  9.08k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  9.08k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  9.08k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  9.08k|            (((uint64_t)(digit))                                            \
  |  |  165|  9.08k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  9.08k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  9.08k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  ------------------
  934|  9.08k|    }
  935|       |
  936|    834|    return h;
  937|    834|}
_h3ToFaceIjkWithInitializedFijk:
 1090|  7.68k|int _h3ToFaceIjkWithInitializedFijk(H3Index h, FaceIJK *fijk) {
 1091|  7.68k|    CoordIJK *ijk = &fijk->coord;
 1092|  7.68k|    int res = H3_GET_RESOLUTION(h);
  ------------------
  |  |  129|  7.68k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  7.68k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  7.68k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  7.68k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
 1093|       |
 1094|       |    // center base cell hierarchy is entirely on this face
 1095|  7.68k|    int possibleOverage = 1;
 1096|  7.68k|    if (!_isBaseCellPentagon(H3_GET_BASE_CELL(h)) &&
  ------------------
  |  |  118|  7.68k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  7.68k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  7.68k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  7.68k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  |  Branch (1096:9): [True: 4.66k, False: 3.02k]
  ------------------
 1097|  4.66k|        (res == 0 ||
  ------------------
  |  Branch (1097:10): [True: 742, False: 3.92k]
  ------------------
 1098|  3.92k|         (fijk->coord.i == 0 && fijk->coord.j == 0 && fijk->coord.k == 0)))
  ------------------
  |  Branch (1098:11): [True: 2.37k, False: 1.54k]
  |  Branch (1098:33): [True: 967, False: 1.41k]
  |  Branch (1098:55): [True: 255, False: 712]
  ------------------
 1099|    997|        possibleOverage = 0;
 1100|       |
 1101|  81.1k|    for (int r = 1; r <= res; r++) {
  ------------------
  |  Branch (1101:21): [True: 73.4k, False: 7.68k]
  ------------------
 1102|  73.4k|        if (isResolutionClassIII(r)) {
  ------------------
  |  Branch (1102:13): [True: 39.5k, False: 33.9k]
  ------------------
 1103|       |            // Class III == rotate ccw
 1104|  39.5k|            _downAp7(ijk);
 1105|  39.5k|        } else {
 1106|       |            // Class II == rotate cw
 1107|  33.9k|            _downAp7r(ijk);
 1108|  33.9k|        }
 1109|       |
 1110|  73.4k|        _neighbor(ijk, H3_GET_INDEX_DIGIT(h, r));
  ------------------
  |  |  141|  73.4k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  73.4k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  73.4k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  73.4k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  73.4k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
 1111|  73.4k|    }
 1112|       |
 1113|  7.68k|    return possibleOverage;
 1114|  7.68k|}
_h3ToFaceIjk:
 1121|  7.70k|H3Error _h3ToFaceIjk(H3Index h, FaceIJK *fijk) {
 1122|  7.70k|    int baseCell = H3_GET_BASE_CELL(h);
  ------------------
  |  |  118|  7.70k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  7.70k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  7.70k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  7.70k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
 1123|  7.70k|    if (NEVER(baseCell < 0) || baseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |  119|  15.4k|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 7.70k]
  |  |  |  Branch (119:19): [True: 0, False: 7.70k]
  |  |  ------------------
  ------------------
                  if (NEVER(baseCell < 0) || baseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |   81|  7.70k|#define NUM_BASE_CELLS 122
  ------------------
  |  Branch (1123:9): [Folded, False: 0]
  |  Branch (1123:9): [Folded, False: 0]
  |  Branch (1123:32): [True: 16, False: 7.68k]
  ------------------
 1124|       |        // Base cells less than zero can not be represented in an index
 1125|       |        // To prevent reading uninitialized memory, we zero the output.
 1126|     16|        fijk->face = 0;
 1127|     16|        fijk->coord.i = fijk->coord.j = fijk->coord.k = 0;
 1128|     16|        return E_CELL_INVALID;
 1129|     16|    }
 1130|       |    // adjust for the pentagonal missing sequence; all of sub-sequence 5 needs
 1131|       |    // to be adjusted (and some of sub-sequence 4 below)
 1132|  7.68k|    if (_isBaseCellPentagon(baseCell) && _h3LeadingNonZeroDigit(h) == 5)
  ------------------
  |  Branch (1132:9): [True: 3.02k, False: 4.66k]
  |  Branch (1132:42): [True: 623, False: 2.40k]
  ------------------
 1133|    623|        h = _h3Rotate60cw(h);
 1134|       |
 1135|       |    // start with the "home" face and ijk+ coordinates for the base cell of c
 1136|  7.68k|    *fijk = baseCellData[baseCell].homeFijk;
 1137|  7.68k|    if (!_h3ToFaceIjkWithInitializedFijk(h, fijk))
  ------------------
  |  Branch (1137:9): [True: 997, False: 6.69k]
  ------------------
 1138|    997|        return E_SUCCESS;  // no overage is possible; h lies on this face
 1139|       |
 1140|       |    // if we're here we have the potential for an "overage"; i.e., it is
 1141|       |    // possible that c lies on an adjacent face
 1142|       |
 1143|  6.69k|    CoordIJK origIJK = fijk->coord;
 1144|       |
 1145|       |    // if we're in Class III, drop into the next finer Class II grid
 1146|  6.69k|    int res = H3_GET_RESOLUTION(h);
  ------------------
  |  |  129|  6.69k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  6.69k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  6.69k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  6.69k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
 1147|  6.69k|    if (isResolutionClassIII(res)) {
  ------------------
  |  Branch (1147:9): [True: 5.37k, False: 1.31k]
  ------------------
 1148|       |        // Class III
 1149|  5.37k|        _downAp7r(&fijk->coord);
 1150|  5.37k|        res++;
 1151|  5.37k|    }
 1152|       |
 1153|       |    // adjust for overage if needed
 1154|       |    // a pentagon base cell with a leading 4 digit requires special handling
 1155|  6.69k|    int pentLeading4 =
 1156|  6.69k|        (_isBaseCellPentagon(baseCell) && _h3LeadingNonZeroDigit(h) == 4);
  ------------------
  |  Branch (1156:10): [True: 3.02k, False: 3.66k]
  |  Branch (1156:43): [True: 897, False: 2.12k]
  ------------------
 1157|  6.69k|    if (_adjustOverageClassII(fijk, res, pentLeading4, 0) != NO_OVERAGE) {
  ------------------
  |  Branch (1157:9): [True: 3.47k, False: 3.21k]
  ------------------
 1158|       |        // if the base cell is a pentagon we have the potential for secondary
 1159|       |        // overages
 1160|  3.47k|        if (_isBaseCellPentagon(baseCell)) {
  ------------------
  |  Branch (1160:13): [True: 2.49k, False: 976]
  ------------------
 1161|  4.30k|            while (_adjustOverageClassII(fijk, res, 0, 0) != NO_OVERAGE)
  ------------------
  |  Branch (1161:20): [True: 1.80k, False: 2.49k]
  ------------------
 1162|  1.80k|                continue;
 1163|  2.49k|        }
 1164|       |
 1165|  3.47k|        if (res != H3_GET_RESOLUTION(h)) _upAp7r(&fijk->coord);
  ------------------
  |  |  129|  3.47k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  3.47k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  3.47k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  3.47k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (1165:13): [True: 2.83k, False: 638]
  ------------------
 1166|  3.47k|    } else if (res != H3_GET_RESOLUTION(h)) {
  ------------------
  |  |  129|  3.21k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  3.21k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  3.21k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  3.21k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (1166:16): [True: 2.53k, False: 679]
  ------------------
 1167|  2.53k|        fijk->coord = origIJK;
 1168|  2.53k|    }
 1169|  6.69k|    return E_SUCCESS;
 1170|  7.68k|}
isResolutionClassIII:
 1359|  96.5k|int isResolutionClassIII(int res) { return res % 2; }
h3Index.c:_hasGoodTopBits:
  216|    241|static inline bool _hasGoodTopBits(H3Index h) {
  217|    241|    h >>= (64 - 8);
  218|    241|    return h == 0b00001000;
  219|    241|}
h3Index.c:_hasAny7UptoRes:
  264|    232|static inline bool _hasAny7UptoRes(H3Index h, int res) {
  265|    232|    const uint64_t MHI = 0b100100100100100100100100100100100100100100100;
  266|    232|    const uint64_t MLO = MHI >> 2;
  267|       |
  268|    232|    int shift = 3 * (15 - res);
  269|    232|    h >>= shift;
  270|    232|    h <<= shift;
  271|    232|    h = (h & MHI & (~h - MLO));
  272|       |
  273|    232|    return h != 0;
  274|    232|}
h3Index.c:_hasAll7AfterRes:
  280|    200|static inline bool _hasAll7AfterRes(H3Index h, int res) {
  281|       |    // NOTE: res check is needed because we can't shift by 64
  282|    200|    if (res < 15) {
  ------------------
  |  Branch (282:9): [True: 102, False: 98]
  ------------------
  283|    102|        int shift = 19 + 3 * res;
  284|       |
  285|    102|        h = ~h;
  286|    102|        h <<= shift;
  287|    102|        h >>= shift;
  288|       |
  289|    102|        return h == 0;
  290|    102|    }
  291|     98|    return true;
  292|    200|}
h3Index.c:_hasDeletedSubsequence:
  327|    138|static inline bool _hasDeletedSubsequence(H3Index h, int base_cell) {
  328|    138|    if (isBaseCellPentagonArr[base_cell]) {
  ------------------
  |  Branch (328:9): [True: 75, False: 63]
  ------------------
  329|     75|        h <<= 19;
  330|     75|        h >>= 19;
  331|       |
  332|     75|        if (h == 0) return false;  // all zeros: res 15 pentagon
  ------------------
  |  Branch (332:13): [True: 1, False: 74]
  ------------------
  333|     74|        return _firstOneIndex(h) % 3 == 0;
  334|     75|    }
  335|     63|    return false;
  336|    138|}
h3Index.c:_firstOneIndex:
  300|     74|static inline int _firstOneIndex(H3Index h) {
  301|     74|#if defined(__GNUC__) || defined(__clang__)
  302|     74|    return 63 - __builtin_clzll(h);
  303|       |#elif defined(_MSC_VER) && defined(_M_X64)  // doesn't work on win32
  304|       |    unsigned long index;
  305|       |    _BitScanReverse64(&index, h);
  306|       |    return (int)index;
  307|       |#else
  308|       |    // Portable fallback
  309|       |    int pos = 63 - 19;
  310|       |    H3Index m = 1;
  311|       |    while ((h & (m << pos)) == 0) pos--;
  312|       |    return pos;
  313|       |#endif
  314|     74|}

_posAngleRads:
   36|    562|double _posAngleRads(double rads) {
   37|    562|    double tmp = ((rads < 0.0) ? rads + M_2PI : rads);
  ------------------
  |  |   34|     59|#define M_2PI 6.28318530717958647692528676655900576839433
  ------------------
  |  Branch (37:19): [True: 59, False: 503]
  ------------------
   38|    562|    if (rads >= M_2PI) tmp -= M_2PI;
  ------------------
  |  |   34|    562|#define M_2PI 6.28318530717958647692528676655900576839433
  ------------------
                  if (rads >= M_2PI) tmp -= M_2PI;
  ------------------
  |  |   34|     60|#define M_2PI 6.28318530717958647692528676655900576839433
  ------------------
  |  Branch (38:9): [True: 60, False: 502]
  ------------------
   39|    562|    return tmp;
   40|    562|}

_v2dMag:
   31|    562|double _v2dMag(const Vec2d *v) { return sqrt(v->x * v->x + v->y * v->y); }

vertexNumForDirection:
  130|  2.10k|int vertexNumForDirection(const H3Index origin, const Direction direction) {
  131|  2.10k|    int isPent = H3_EXPORT(isPentagon)(origin);
  ------------------
  |  |   36|  2.10k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  2.10k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  2.10k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  132|       |    // Check for invalid directions
  133|  2.10k|    if (direction == CENTER_DIGIT || direction >= INVALID_DIGIT ||
  ------------------
  |  Branch (133:9): [True: 0, False: 2.10k]
  |  Branch (133:38): [True: 20, False: 2.08k]
  ------------------
  134|  2.08k|        (isPent && direction == K_AXES_DIGIT))
  ------------------
  |  Branch (134:10): [True: 121, False: 1.96k]
  |  Branch (134:20): [True: 0, False: 121]
  ------------------
  135|     20|        return INVALID_VERTEX_NUM;
  ------------------
  |  |   36|     20|#define INVALID_VERTEX_NUM -1
  ------------------
  136|       |
  137|       |    // Determine the vertex rotations for this cell
  138|  2.08k|    int rotations;
  139|  2.08k|    H3Error err = vertexRotations(origin, &rotations);
  140|  2.08k|    if (err) {
  ------------------
  |  Branch (140:9): [True: 0, False: 2.08k]
  ------------------
  141|      0|        return INVALID_VERTEX_NUM;
  ------------------
  |  |   36|      0|#define INVALID_VERTEX_NUM -1
  ------------------
  142|      0|    }
  143|       |
  144|       |    // Find the appropriate vertex, rotating CCW if necessary
  145|  2.08k|    if (isPent) {
  ------------------
  |  Branch (145:9): [True: 121, False: 1.96k]
  ------------------
  146|    121|        return (directionToVertexNumPent[direction] + NUM_PENT_VERTS -
  ------------------
  |  |   85|    121|#define NUM_PENT_VERTS 5
  ------------------
  147|    121|                rotations) %
  148|    121|               NUM_PENT_VERTS;
  ------------------
  |  |   85|    121|#define NUM_PENT_VERTS 5
  ------------------
  149|  1.96k|    } else {
  150|  1.96k|        return (directionToVertexNumHex[direction] + NUM_HEX_VERTS -
  ------------------
  |  |   83|  1.96k|#define NUM_HEX_VERTS 6
  ------------------
  151|  1.96k|                rotations) %
  152|  1.96k|               NUM_HEX_VERTS;
  ------------------
  |  |   83|  1.96k|#define NUM_HEX_VERTS 6
  ------------------
  153|  1.96k|    }
  154|  2.08k|}
directionForVertexNum:
  173|  5.05k|Direction directionForVertexNum(const H3Index origin, const int vertexNum) {
  174|  5.05k|    int isPent = H3_EXPORT(isPentagon)(origin);
  ------------------
  |  |   36|  5.05k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  5.05k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  5.05k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  175|       |    // Check for invalid vertexes
  176|  5.05k|    if (vertexNum < 0 ||
  ------------------
  |  Branch (176:9): [True: 0, False: 5.05k]
  ------------------
  177|  5.05k|        vertexNum > (isPent ? NUM_PENT_VERTS : NUM_HEX_VERTS) - 1)
  ------------------
  |  |   85|     46|#define NUM_PENT_VERTS 5
  ------------------
                      vertexNum > (isPent ? NUM_PENT_VERTS : NUM_HEX_VERTS) - 1)
  ------------------
  |  |   83|  5.00k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (177:9): [True: 0, False: 5.05k]
  |  Branch (177:22): [True: 46, False: 5.00k]
  ------------------
  178|      0|        return INVALID_DIGIT;
  179|       |
  180|       |    // Determine the vertex rotations for this cell
  181|  5.05k|    int rotations;
  182|  5.05k|    H3Error err = vertexRotations(origin, &rotations);
  183|  5.05k|    if (err) {
  ------------------
  |  Branch (183:9): [True: 8, False: 5.04k]
  ------------------
  184|      8|        return INVALID_DIGIT;
  185|      8|    }
  186|       |
  187|       |    // Find the appropriate direction, rotating CW if necessary
  188|  5.04k|    return isPent ? vertexNumToDirectionPent[(vertexNum + rotations) %
  ------------------
  |  Branch (188:12): [True: 46, False: 4.99k]
  ------------------
  189|     46|                                             NUM_PENT_VERTS]
  ------------------
  |  |   85|     46|#define NUM_PENT_VERTS 5
  ------------------
  190|  5.04k|                  : vertexNumToDirectionHex[(vertexNum + rotations) %
  191|  4.99k|                                            NUM_HEX_VERTS];
  ------------------
  |  |   83|  4.99k|#define NUM_HEX_VERTS 6
  ------------------
  192|  5.05k|}
cellToVertex:
  212|  3.53k|H3Error H3_EXPORT(cellToVertex)(H3Index cell, int vertexNum, H3Index *out) {
  213|  3.53k|    int cellIsPentagon = H3_EXPORT(isPentagon)(cell);
  ------------------
  |  |   36|  3.53k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  3.53k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  3.53k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  214|  3.53k|    int cellNumVerts = cellIsPentagon ? NUM_PENT_VERTS : NUM_HEX_VERTS;
  ------------------
  |  |   85|    130|#define NUM_PENT_VERTS 5
  ------------------
                  int cellNumVerts = cellIsPentagon ? NUM_PENT_VERTS : NUM_HEX_VERTS;
  ------------------
  |  |   83|  3.40k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (214:24): [True: 130, False: 3.40k]
  ------------------
  215|  3.53k|    int res = H3_GET_RESOLUTION(cell);
  ------------------
  |  |  129|  3.53k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  3.53k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  3.53k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  3.53k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  216|       |
  217|       |    // Check for invalid vertexes
  218|  3.53k|    if (vertexNum < 0 || vertexNum > cellNumVerts - 1) return E_DOMAIN;
  ------------------
  |  Branch (218:9): [True: 153, False: 3.38k]
  |  Branch (218:26): [True: 283, False: 3.10k]
  ------------------
  219|       |
  220|       |    // Default the owner and vertex number to the input cell
  221|  3.10k|    H3Index owner = cell;
  222|  3.10k|    int ownerVertexNum = vertexNum;
  223|       |
  224|       |    // Determine the owner, looking at the three cells that share the vertex.
  225|       |    // By convention, the owner is the cell with the lowest numerical index.
  226|       |
  227|       |    // If the cell is the center child of its parent, it will always have
  228|       |    // the lowest index of any neighbor, so we can skip determining the owner
  229|  3.10k|    if (res == 0 || H3_GET_INDEX_DIGIT(cell, res) != CENTER_DIGIT) {
  ------------------
  |  |  141|  2.79k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  2.79k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  2.79k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  2.79k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  2.79k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  |  Branch (229:9): [True: 311, False: 2.79k]
  |  Branch (229:21): [True: 2.46k, False: 328]
  ------------------
  230|       |        // Get the left neighbor of the vertex, with its rotations
  231|  2.77k|        Direction left = directionForVertexNum(cell, vertexNum);
  232|  2.77k|        if (left == INVALID_DIGIT) return E_FAILED;
  ------------------
  |  Branch (232:13): [True: 8, False: 2.76k]
  ------------------
  233|  2.76k|        int lRotations = 0;
  234|  2.76k|        H3Index leftNeighbor;
  235|  2.76k|        H3Error leftNeighborError =
  236|  2.76k|            h3NeighborRotations(cell, left, &lRotations, &leftNeighbor);
  237|  2.76k|        if (leftNeighborError) return leftNeighborError;
  ------------------
  |  Branch (237:13): [True: 102, False: 2.66k]
  ------------------
  238|       |        // Set to owner if lowest index
  239|  2.66k|        if (leftNeighbor < owner) owner = leftNeighbor;
  ------------------
  |  Branch (239:13): [True: 1.60k, False: 1.05k]
  ------------------
  240|       |
  241|       |        // As above, skip the right neighbor if the left is known lowest
  242|  2.66k|        if (res == 0 || H3_GET_INDEX_DIGIT(leftNeighbor, res) != CENTER_DIGIT) {
  ------------------
  |  |  141|  2.35k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  2.35k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  2.35k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  2.35k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  2.35k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  |  Branch (242:13): [True: 308, False: 2.35k]
  |  Branch (242:25): [True: 1.97k, False: 385]
  ------------------
  243|       |            // Get the right neighbor of the vertex, with its rotations
  244|       |            // Note that vertex - 1 is the right side, as vertex numbers are CCW
  245|  2.27k|            Direction right = directionForVertexNum(
  246|  2.27k|                cell, (vertexNum - 1 + cellNumVerts) % cellNumVerts);
  247|       |            // This case should be unreachable; invalid verts fail earlier
  248|  2.27k|            if (NEVER(right == INVALID_DIGIT)) return E_FAILED;
  ------------------
  |  |  119|  2.27k|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 2.27k]
  |  |  |  Branch (119:19): [True: 0, False: 2.27k]
  |  |  ------------------
  ------------------
  |  Branch (248:17): [Folded, False: 0]
  |  Branch (248:17): [Folded, False: 0]
  ------------------
  249|  2.27k|            int rRotations = 0;
  250|  2.27k|            H3Index rightNeighbor;
  251|  2.27k|            H3Error rightNeighborError =
  252|  2.27k|                h3NeighborRotations(cell, right, &rRotations, &rightNeighbor);
  253|  2.27k|            if (rightNeighborError) return rightNeighborError;
  ------------------
  |  Branch (253:17): [True: 28, False: 2.25k]
  ------------------
  254|       |            // Set to owner if lowest index
  255|  2.25k|            if (rightNeighbor < owner) {
  ------------------
  |  Branch (255:17): [True: 1.05k, False: 1.19k]
  ------------------
  256|  1.05k|                owner = rightNeighbor;
  257|  1.05k|                Direction dir =
  258|  1.05k|                    H3_EXPORT(isPentagon)(owner)
  ------------------
  |  |   36|  1.05k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  1.05k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  1.05k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (258:21): [True: 76, False: 979]
  ------------------
  259|  1.05k|                        ? directionForNeighbor(owner, cell)
  260|  1.05k|                        : DIRECTIONS[(revNeighborDirectionsHex[right] +
  261|    979|                                      rRotations) %
  262|    979|                                     NUM_HEX_VERTS];
  ------------------
  |  |   83|    979|#define NUM_HEX_VERTS 6
  ------------------
  263|  1.05k|                ownerVertexNum = vertexNumForDirection(owner, dir);
  264|  1.05k|            }
  265|  2.25k|        }
  266|       |
  267|       |        // Determine the vertex number for the left neighbor
  268|  2.63k|        if (owner == leftNeighbor) {
  ------------------
  |  Branch (268:13): [True: 1.04k, False: 1.58k]
  ------------------
  269|  1.04k|            int ownerIsPentagon = H3_EXPORT(isPentagon)(owner);
  ------------------
  |  |   36|  1.04k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  1.04k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  1.04k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  270|  1.04k|            Direction dir =
  271|  1.04k|                ownerIsPentagon
  ------------------
  |  Branch (271:17): [True: 65, False: 983]
  ------------------
  272|  1.04k|                    ? directionForNeighbor(owner, cell)
  273|  1.04k|                    : DIRECTIONS[(revNeighborDirectionsHex[left] + lRotations) %
  274|    983|                                 NUM_HEX_VERTS];
  ------------------
  |  |   83|    983|#define NUM_HEX_VERTS 6
  ------------------
  275|       |
  276|       |            // For the left neighbor, we need the second vertex of the
  277|       |            // edge, which may involve looping around the vertex nums
  278|  1.04k|            ownerVertexNum = vertexNumForDirection(owner, dir) + 1;
  279|  1.04k|            if (ownerVertexNum == NUM_HEX_VERTS ||
  ------------------
  |  |   83|  2.09k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (279:17): [True: 170, False: 878]
  ------------------
  280|    878|                (ownerIsPentagon && ownerVertexNum == NUM_PENT_VERTS)) {
  ------------------
  |  |   85|     65|#define NUM_PENT_VERTS 5
  ------------------
  |  Branch (280:18): [True: 65, False: 813]
  |  Branch (280:37): [True: 7, False: 58]
  ------------------
  281|    177|                ownerVertexNum = 0;
  282|    177|            }
  283|  1.04k|        }
  284|  2.63k|    }
  285|       |
  286|       |    // Create the vertex index
  287|  2.96k|    H3Index vertex = owner;
  288|  2.96k|    H3_SET_MODE(vertex, H3_VERTEX_MODE);
  ------------------
  |  |  113|  2.96k|    (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   59|  2.96k|#define H3_MODE_MASK_NEGATIVE (~H3_MODE_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   56|  2.96k|#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   35|  2.96k|#define H3_MODE_OFFSET 59
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   35|  2.96k|#define H3_MODE_OFFSET 59
  |  |  ------------------
  ------------------
  289|  2.96k|    H3_SET_RESERVED_BITS(vertex, ownerVertexNum);
  ------------------
  |  |  149|  2.96k|    (h3) = (((h3)&H3_RESERVED_MASK_NEGATIVE) | \
  |  |  ------------------
  |  |  |  |   77|  2.96k|#define H3_RESERVED_MASK_NEGATIVE (~H3_RESERVED_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   74|  2.96k|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   44|  2.96k|#define H3_RESERVED_OFFSET 56
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  150|  2.96k|            (((uint64_t)(v)) << H3_RESERVED_OFFSET))
  |  |  ------------------
  |  |  |  |   44|  2.96k|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  290|  2.96k|    *out = vertex;
  291|       |
  292|  2.96k|    return E_SUCCESS;
  293|  3.10k|}
cellToVertexes:
  300|    570|H3Error H3_EXPORT(cellToVertexes)(H3Index cell, H3Index *vertexes) {
  301|       |    // Get all vertexes. If the cell is a pentagon, will fill the final slot
  302|       |    // with H3_NULL.
  303|    570|    bool isPent = H3_EXPORT(isPentagon)(cell);
  ------------------
  |  |   36|    570|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    570|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    570|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  304|  3.30k|    for (int i = 0; i < NUM_HEX_VERTS; i++) {
  ------------------
  |  |   83|  3.30k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (304:21): [True: 2.85k, False: 448]
  ------------------
  305|  2.85k|        if (i == 5 && isPent) {
  ------------------
  |  Branch (305:13): [True: 448, False: 2.41k]
  |  Branch (305:23): [True: 21, False: 427]
  ------------------
  306|     21|            vertexes[i] = H3_NULL;
  ------------------
  |  |   76|     21|#define H3_NULL 0
  ------------------
  307|  2.83k|        } else {
  308|  2.83k|            H3Error cellError = H3_EXPORT(cellToVertex)(cell, i, &vertexes[i]);
  ------------------
  |  |   36|  2.83k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  2.83k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  2.83k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  309|  2.83k|            if (cellError) {
  ------------------
  |  Branch (309:17): [True: 122, False: 2.71k]
  ------------------
  310|    122|                return cellError;
  311|    122|            }
  312|  2.83k|        }
  313|  2.85k|    }
  314|    448|    return E_SUCCESS;
  315|    570|}
vertexToLatLng:
  322|    570|H3Error H3_EXPORT(vertexToLatLng)(H3Index vertex, LatLng *coord) {
  323|       |    // Get the vertex number and owner from the vertex
  324|    570|    int vertexNum = H3_GET_RESERVED_BITS(vertex);
  ------------------
  |  |  156|    570|    ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET)))
  |  |  ------------------
  |  |  |  |   74|    570|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|    570|#define H3_RESERVED_OFFSET 56
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET)))
  |  |  ------------------
  |  |  |  |   44|    570|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  325|    570|    H3Index owner = vertex;
  326|    570|    H3_SET_MODE(owner, H3_CELL_MODE);
  ------------------
  |  |  113|    570|    (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   59|    570|#define H3_MODE_MASK_NEGATIVE (~H3_MODE_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   56|    570|#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   35|    570|#define H3_MODE_OFFSET 59
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   35|    570|#define H3_MODE_OFFSET 59
  |  |  ------------------
  ------------------
  327|    570|    H3_SET_RESERVED_BITS(owner, 0);
  ------------------
  |  |  149|    570|    (h3) = (((h3)&H3_RESERVED_MASK_NEGATIVE) | \
  |  |  ------------------
  |  |  |  |   77|    570|#define H3_RESERVED_MASK_NEGATIVE (~H3_RESERVED_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   74|    570|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   44|    570|#define H3_RESERVED_OFFSET 56
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  150|    570|            (((uint64_t)(v)) << H3_RESERVED_OFFSET))
  |  |  ------------------
  |  |  |  |   44|    570|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  328|       |
  329|       |    // Get the single vertex from the boundary
  330|    570|    CellBoundary gb;
  331|    570|    FaceIJK fijk;
  332|    570|    H3Error fijkError = _h3ToFaceIjk(owner, &fijk);
  333|    570|    if (fijkError) {
  ------------------
  |  Branch (333:9): [True: 8, False: 562]
  ------------------
  334|      8|        return fijkError;
  335|      8|    }
  336|    562|    int res = H3_GET_RESOLUTION(owner);
  ------------------
  |  |  129|    562|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|    562|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|    562|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|    562|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  337|       |
  338|    562|    if (H3_EXPORT(isPentagon)(owner)) {
  ------------------
  |  |   36|    562|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    562|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    562|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (338:9): [True: 21, False: 541]
  ------------------
  339|     21|        _faceIjkPentToCellBoundary(&fijk, res, vertexNum, 1, &gb);
  340|    541|    } else {
  341|    541|        _faceIjkToCellBoundary(&fijk, res, vertexNum, 1, &gb);
  342|    541|    }
  343|       |
  344|       |    // Copy from boundary to output coord
  345|    562|    *coord = gb.verts[0];
  346|    562|    return E_SUCCESS;
  347|    570|}
isValidVertex:
  354|    570|int H3_EXPORT(isValidVertex)(H3Index vertex) {
  355|    570|    if (H3_GET_MODE(vertex) != H3_VERTEX_MODE) {
  ------------------
  |  |  107|    570|#define H3_GET_MODE(h3) ((int)((((h3)&H3_MODE_MASK) >> H3_MODE_OFFSET)))
  |  |  ------------------
  |  |  |  |   56|    570|#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   35|    570|#define H3_MODE_OFFSET 59
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_MODE(h3) ((int)((((h3)&H3_MODE_MASK) >> H3_MODE_OFFSET)))
  |  |  ------------------
  |  |  |  |   35|    570|#define H3_MODE_OFFSET 59
  |  |  ------------------
  ------------------
                  if (H3_GET_MODE(vertex) != H3_VERTEX_MODE) {
  ------------------
  |  |   93|    570|#define H3_VERTEX_MODE 4
  ------------------
  |  Branch (355:9): [True: 329, False: 241]
  ------------------
  356|    329|        return 0;
  357|    329|    }
  358|       |
  359|    241|    int vertexNum = H3_GET_RESERVED_BITS(vertex);
  ------------------
  |  |  156|    241|    ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET)))
  |  |  ------------------
  |  |  |  |   74|    241|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|    241|#define H3_RESERVED_OFFSET 56
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET)))
  |  |  ------------------
  |  |  |  |   44|    241|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  360|    241|    H3Index owner = vertex;
  361|    241|    H3_SET_MODE(owner, H3_CELL_MODE);
  ------------------
  |  |  113|    241|    (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   59|    241|#define H3_MODE_MASK_NEGATIVE (~H3_MODE_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   56|    241|#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   35|    241|#define H3_MODE_OFFSET 59
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   35|    241|#define H3_MODE_OFFSET 59
  |  |  ------------------
  ------------------
  362|    241|    H3_SET_RESERVED_BITS(owner, 0);
  ------------------
  |  |  149|    241|    (h3) = (((h3)&H3_RESERVED_MASK_NEGATIVE) | \
  |  |  ------------------
  |  |  |  |   77|    241|#define H3_RESERVED_MASK_NEGATIVE (~H3_RESERVED_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   74|    241|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   44|    241|#define H3_RESERVED_OFFSET 56
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  150|    241|            (((uint64_t)(v)) << H3_RESERVED_OFFSET))
  |  |  ------------------
  |  |  |  |   44|    241|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  363|       |
  364|    241|    if (!H3_EXPORT(isValidCell)(owner)) {
  ------------------
  |  |   36|    241|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    241|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    241|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (364:9): [True: 111, False: 130]
  ------------------
  365|    111|        return 0;
  366|    111|    }
  367|       |
  368|       |    // The easiest way to ensure that the owner + vertex number is valid,
  369|       |    // and that the vertex is canonical, is to recreate and compare.
  370|    130|    H3Index canonical;
  371|    130|    if (H3_EXPORT(cellToVertex)(owner, vertexNum, &canonical)) {
  ------------------
  |  |   36|    130|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    130|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    130|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (371:9): [True: 5, False: 125]
  ------------------
  372|      5|        return 0;
  373|      5|    }
  374|       |
  375|    125|    return vertex == canonical ? 1 : 0;
  ------------------
  |  Branch (375:12): [True: 17, False: 108]
  ------------------
  376|    130|}
vertex.c:vertexRotations:
   53|  7.13k|static H3Error vertexRotations(H3Index cell, int *out) {
   54|       |    // Get the face and other info for the origin
   55|  7.13k|    FaceIJK fijk;
   56|  7.13k|    H3Error err = _h3ToFaceIjk(cell, &fijk);
   57|  7.13k|    if (err) {
  ------------------
  |  Branch (57:9): [True: 8, False: 7.12k]
  ------------------
   58|      8|        return err;
   59|      8|    }
   60|  7.12k|    int baseCell = H3_EXPORT(getBaseCellNumber)(cell);
  ------------------
  |  |   36|  7.12k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  7.12k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  7.12k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   61|  7.12k|    int cellLeadingDigit = _h3LeadingNonZeroDigit(cell);
   62|       |
   63|       |    // get the base cell face
   64|  7.12k|    FaceIJK baseFijk;
   65|  7.12k|    _baseCellToFaceIjk(baseCell, &baseFijk);
   66|       |
   67|  7.12k|    int ccwRot60 = _baseCellToCCWrot60(baseCell, fijk.face);
   68|       |
   69|  7.12k|    if (_isBaseCellPentagon(baseCell)) {
  ------------------
  |  Branch (69:9): [True: 2.78k, False: 4.34k]
  ------------------
   70|       |        // Find the appropriate direction-to-face mapping
   71|  2.78k|        PentagonDirectionFaces dirFaces;
   72|       |        // We never hit the end condition
   73|  2.78k|        int p = 0;
   74|       |        // Don't use a for loop here, for coverage reasons.
   75|  17.6k|        while (ALWAYS(p < NUM_PENTAGONS)) {
  ------------------
  |  |  118|  17.6k|#define ALWAYS(X) ((X) ? 1 : (assert(0), 0))
  |  |  ------------------
  |  |  |  Branch (118:19): [True: 17.6k, False: 0]
  |  |  |  Branch (118:20): [True: 17.6k, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (75:16): [Folded, False: 0]
  |  Branch (75:16): [Folded, False: 0]
  ------------------
   76|  17.6k|            if (pentagonDirectionFaces[p].baseCell == baseCell) {
  ------------------
  |  Branch (76:17): [True: 2.78k, False: 14.9k]
  ------------------
   77|  2.78k|                dirFaces = pentagonDirectionFaces[p];
   78|  2.78k|                break;
   79|  2.78k|            }
   80|  14.9k|            p++;
   81|  14.9k|        }
   82|  2.78k|        if (NEVER(p == NUM_PENTAGONS)) {
  ------------------
  |  |  119|  2.78k|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 2.78k]
  |  |  |  Branch (119:19): [True: 0, False: 2.78k]
  |  |  ------------------
  ------------------
  |  Branch (82:13): [Folded, False: 0]
  |  Branch (82:13): [Folded, False: 0]
  ------------------
   83|      0|            return E_FAILED;
   84|      0|        }
   85|       |
   86|       |        // additional CCW rotation for polar neighbors or IK neighbors
   87|  2.78k|        if (fijk.face != baseFijk.face &&
  ------------------
  |  Branch (87:13): [True: 2.30k, False: 481]
  ------------------
   88|  2.30k|            (_isBaseCellPolarPentagon(baseCell) ||
  ------------------
  |  Branch (88:14): [True: 781, False: 1.51k]
  ------------------
   89|  1.51k|             fijk.face ==
  ------------------
  |  Branch (89:14): [True: 520, False: 999]
  ------------------
   90|  1.51k|                 dirFaces.faces[IK_AXES_DIGIT - DIRECTION_INDEX_OFFSET])) {
  ------------------
  |  |   32|  1.51k|#define DIRECTION_INDEX_OFFSET 2
  ------------------
   91|  1.30k|            ccwRot60 = (ccwRot60 + 1) % 6;
   92|  1.30k|        }
   93|       |
   94|       |        // Check whether the cell crosses a deleted pentagon subsequence
   95|  2.78k|        if (cellLeadingDigit == JK_AXES_DIGIT &&
  ------------------
  |  Branch (95:13): [True: 490, False: 2.29k]
  ------------------
   96|    490|            fijk.face ==
  ------------------
  |  Branch (96:13): [True: 264, False: 226]
  ------------------
   97|    490|                dirFaces.faces[IK_AXES_DIGIT - DIRECTION_INDEX_OFFSET]) {
  ------------------
  |  |   32|    490|#define DIRECTION_INDEX_OFFSET 2
  ------------------
   98|       |            // Crosses from JK to IK: Rotate CW
   99|    264|            ccwRot60 = (ccwRot60 + 5) % 6;
  100|  2.51k|        } else if (cellLeadingDigit == IK_AXES_DIGIT &&
  ------------------
  |  Branch (100:20): [True: 580, False: 1.93k]
  ------------------
  101|    580|                   fijk.face ==
  ------------------
  |  Branch (101:20): [True: 76, False: 504]
  ------------------
  102|    580|                       dirFaces.faces[JK_AXES_DIGIT - DIRECTION_INDEX_OFFSET]) {
  ------------------
  |  |   32|    580|#define DIRECTION_INDEX_OFFSET 2
  ------------------
  103|       |            // Crosses from IK to JK: Rotate CCW
  104|     76|            ccwRot60 = (ccwRot60 + 1) % 6;
  105|     76|        }
  106|  2.78k|    }
  107|  7.12k|    *out = ccwRot60;
  108|  7.12k|    return E_SUCCESS;
  109|  7.12k|}

