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

faceijk.c:_ijkToHex2d:
  244|    582|static inline void _ijkToHex2d(const CoordIJK *h, Vec2d *v) {
  245|    582|    int i = h->i - h->k;
  246|    582|    int j = h->j - h->k;
  247|       |
  248|    582|    v->x = i - 0.5 * j;
  249|    582|    v->y = j * M_SQRT3_2;
  ------------------
  |  |   44|    582|#define M_SQRT3_2 0.8660254037844386467637231707529361834714
  ------------------
  250|    582|}
faceijk.c:_ijkRotate60ccw:
  614|  19.8k|static inline void _ijkRotate60ccw(CoordIJK *ijk) {
  615|       |    // unit vector rotations
  616|  19.8k|    CoordIJK iVec = {1, 1, 0};
  617|  19.8k|    CoordIJK jVec = {0, 1, 1};
  618|  19.8k|    CoordIJK kVec = {1, 0, 1};
  619|       |
  620|  19.8k|    _ijkScale(&iVec, ijk->i);
  621|  19.8k|    _ijkScale(&jVec, ijk->j);
  622|  19.8k|    _ijkScale(&kVec, ijk->k);
  623|       |
  624|  19.8k|    _ijkAdd(&iVec, &jVec, ijk);
  625|  19.8k|    _ijkAdd(ijk, &kVec, ijk);
  626|       |
  627|  19.8k|    _ijkNormalize(ijk);
  628|  19.8k|}
faceijk.c:_ijkScale:
  155|  72.3k|static inline void _ijkScale(CoordIJK *c, int factor) {
  156|  72.3k|    c->i *= factor;
  157|  72.3k|    c->j *= factor;
  158|  72.3k|    c->k *= factor;
  159|  72.3k|}
faceijk.c:_ijkAdd:
  129|  54.3k|                           CoordIJK *sum) {
  130|  54.3k|    sum->i = h1->i + h2->i;
  131|  54.3k|    sum->j = h1->j + h2->j;
  132|  54.3k|    sum->k = h1->k + h2->k;
  133|  54.3k|}
faceijk.c:_ijkNormalize:
  207|  31.8k|static inline void _ijkNormalize(CoordIJK *c) {
  208|       |    // remove any negative values
  209|  31.8k|    if (c->i < 0) {
  ------------------
  |  Branch (209:9): [True: 0, False: 31.8k]
  ------------------
  210|      0|        c->j -= c->i;
  211|      0|        c->k -= c->i;
  212|      0|        c->i = 0;
  213|      0|    }
  214|       |
  215|  31.8k|    if (c->j < 0) {
  ------------------
  |  Branch (215:9): [True: 0, False: 31.8k]
  ------------------
  216|      0|        c->i -= c->j;
  217|      0|        c->k -= c->j;
  218|      0|        c->j = 0;
  219|      0|    }
  220|       |
  221|  31.8k|    if (c->k < 0) {
  ------------------
  |  Branch (221:9): [True: 0, False: 31.8k]
  ------------------
  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|  31.8k|    int min = c->i;
  229|  31.8k|    if (c->j < min) min = c->j;
  ------------------
  |  Branch (229:9): [True: 14.2k, False: 17.5k]
  ------------------
  230|  31.8k|    if (c->k < min) min = c->k;
  ------------------
  |  Branch (230:9): [True: 11.3k, False: 20.4k]
  ------------------
  231|  31.8k|    if (min > 0) {
  ------------------
  |  Branch (231:9): [True: 30.2k, False: 1.61k]
  ------------------
  232|  30.2k|        c->i -= min;
  233|  30.2k|        c->j -= min;
  234|  30.2k|        c->k -= min;
  235|  30.2k|    }
  236|  31.8k|}
faceijk.c:_downAp3:
  557|    582|static inline void _downAp3(CoordIJK *ijk) {
  558|       |    // res r unit vectors in res r+1
  559|    582|    CoordIJK iVec = {2, 0, 1};
  560|    582|    CoordIJK jVec = {1, 2, 0};
  561|    582|    CoordIJK kVec = {0, 1, 2};
  562|       |
  563|    582|    _ijkScale(&iVec, ijk->i);
  564|    582|    _ijkScale(&jVec, ijk->j);
  565|    582|    _ijkScale(&kVec, ijk->k);
  566|       |
  567|    582|    _ijkAdd(&iVec, &jVec, ijk);
  568|    582|    _ijkAdd(ijk, &kVec, ijk);
  569|       |
  570|    582|    _ijkNormalize(ijk);
  571|    582|}
faceijk.c:_downAp3r:
  579|    582|static inline void _downAp3r(CoordIJK *ijk) {
  580|       |    // res r unit vectors in res r+1
  581|    582|    CoordIJK iVec = {2, 1, 0};
  582|    582|    CoordIJK jVec = {0, 2, 1};
  583|    582|    CoordIJK kVec = {1, 0, 2};
  584|       |
  585|    582|    _ijkScale(&iVec, ijk->i);
  586|    582|    _ijkScale(&jVec, ijk->j);
  587|    582|    _ijkScale(&kVec, ijk->k);
  588|       |
  589|    582|    _ijkAdd(&iVec, &jVec, ijk);
  590|    582|    _ijkAdd(ijk, &kVec, ijk);
  591|       |
  592|    582|    _ijkNormalize(ijk);
  593|    582|}
faceijk.c:_downAp7r:
  534|    418|static inline void _downAp7r(CoordIJK *ijk) {
  535|       |    // res r unit vectors in res r+1
  536|    418|    CoordIJK iVec = {3, 1, 0};
  537|    418|    CoordIJK jVec = {0, 3, 1};
  538|    418|    CoordIJK kVec = {1, 0, 3};
  539|       |
  540|    418|    _ijkScale(&iVec, ijk->i);
  541|    418|    _ijkScale(&jVec, ijk->j);
  542|    418|    _ijkScale(&kVec, ijk->k);
  543|       |
  544|    418|    _ijkAdd(&iVec, &jVec, ijk);
  545|    418|    _ijkAdd(ijk, &kVec, ijk);
  546|       |
  547|    418|    _ijkNormalize(ijk);
  548|    418|}
faceijk.c:_setIJK:
  103|    565|static inline void _setIJK(CoordIJK *ijk, int i, int j, int k) {
  104|    565|    ijk->i = i;
  105|    565|    ijk->j = j;
  106|    565|    ijk->k = k;
  107|    565|}
faceijk.c:_ijkSub:
  143|    565|                           CoordIJK *diff) {
  144|    565|    diff->i = h1->i - h2->i;
  145|    565|    diff->j = h1->j - h2->j;
  146|    565|    diff->k = h1->k - h2->k;
  147|    565|}
faceijk.c:_ijkRotate60cw:
  635|    565|static inline void _ijkRotate60cw(CoordIJK *ijk) {
  636|       |    // unit vector rotations
  637|    565|    CoordIJK iVec = {1, 0, 1};
  638|    565|    CoordIJK jVec = {1, 1, 0};
  639|    565|    CoordIJK kVec = {0, 1, 1};
  640|       |
  641|    565|    _ijkScale(&iVec, ijk->i);
  642|    565|    _ijkScale(&jVec, ijk->j);
  643|    565|    _ijkScale(&kVec, ijk->k);
  644|       |
  645|    565|    _ijkAdd(&iVec, &jVec, ijk);
  646|    565|    _ijkAdd(ijk, &kVec, ijk);
  647|       |
  648|    565|    _ijkNormalize(ijk);
  649|    565|}
h3Index.c:_rotate60ccw:
  656|  10.2k|static inline Direction _rotate60ccw(Direction digit) {
  657|  10.2k|    switch (digit) {
  658|  2.08k|        case K_AXES_DIGIT:
  ------------------
  |  Branch (658:9): [True: 2.08k, False: 8.13k]
  ------------------
  659|  2.08k|            return IK_AXES_DIGIT;
  660|  1.72k|        case IK_AXES_DIGIT:
  ------------------
  |  Branch (660:9): [True: 1.72k, False: 8.49k]
  ------------------
  661|  1.72k|            return I_AXES_DIGIT;
  662|  1.37k|        case I_AXES_DIGIT:
  ------------------
  |  Branch (662:9): [True: 1.37k, False: 8.84k]
  ------------------
  663|  1.37k|            return IJ_AXES_DIGIT;
  664|  1.26k|        case IJ_AXES_DIGIT:
  ------------------
  |  Branch (664:9): [True: 1.26k, False: 8.95k]
  ------------------
  665|  1.26k|            return J_AXES_DIGIT;
  666|  1.57k|        case J_AXES_DIGIT:
  ------------------
  |  Branch (666:9): [True: 1.57k, False: 8.63k]
  ------------------
  667|  1.57k|            return JK_AXES_DIGIT;
  668|  1.91k|        case JK_AXES_DIGIT:
  ------------------
  |  Branch (668:9): [True: 1.91k, False: 8.29k]
  ------------------
  669|  1.91k|            return K_AXES_DIGIT;
  670|    282|        default:
  ------------------
  |  Branch (670:9): [True: 282, False: 9.93k]
  ------------------
  671|    282|            return digit;
  672|  10.2k|    }
  673|  10.2k|}
h3Index.c:_rotate60cw:
  680|  8.66k|static inline Direction _rotate60cw(Direction digit) {
  681|  8.66k|    switch (digit) {
  682|    930|        case K_AXES_DIGIT:
  ------------------
  |  Branch (682:9): [True: 930, False: 7.73k]
  ------------------
  683|    930|            return JK_AXES_DIGIT;
  684|    915|        case JK_AXES_DIGIT:
  ------------------
  |  Branch (684:9): [True: 915, False: 7.75k]
  ------------------
  685|    915|            return J_AXES_DIGIT;
  686|    792|        case J_AXES_DIGIT:
  ------------------
  |  Branch (686:9): [True: 792, False: 7.87k]
  ------------------
  687|    792|            return IJ_AXES_DIGIT;
  688|    777|        case IJ_AXES_DIGIT:
  ------------------
  |  Branch (688:9): [True: 777, False: 7.88k]
  ------------------
  689|    777|            return I_AXES_DIGIT;
  690|  1.03k|        case I_AXES_DIGIT:
  ------------------
  |  Branch (690:9): [True: 1.03k, False: 7.63k]
  ------------------
  691|  1.03k|            return IK_AXES_DIGIT;
  692|  1.62k|        case IK_AXES_DIGIT:
  ------------------
  |  Branch (692:9): [True: 1.62k, False: 7.04k]
  ------------------
  693|  1.62k|            return K_AXES_DIGIT;
  694|  2.59k|        default:
  ------------------
  |  Branch (694:9): [True: 2.59k, False: 6.06k]
  ------------------
  695|  2.59k|            return digit;
  696|  8.66k|    }
  697|  8.66k|}
h3Index.c:_downAp7:
  512|  41.7k|static inline void _downAp7(CoordIJK *ijk) {
  513|       |    // res r unit vectors in res r+1
  514|  41.7k|    CoordIJK iVec = {3, 0, 1};
  515|  41.7k|    CoordIJK jVec = {1, 3, 0};
  516|  41.7k|    CoordIJK kVec = {0, 1, 3};
  517|       |
  518|  41.7k|    _ijkScale(&iVec, ijk->i);
  519|  41.7k|    _ijkScale(&jVec, ijk->j);
  520|  41.7k|    _ijkScale(&kVec, ijk->k);
  521|       |
  522|  41.7k|    _ijkAdd(&iVec, &jVec, ijk);
  523|  41.7k|    _ijkAdd(ijk, &kVec, ijk);
  524|       |
  525|  41.7k|    _ijkNormalize(ijk);
  526|  41.7k|}
h3Index.c:_ijkScale:
  155|   249k|static inline void _ijkScale(CoordIJK *c, int factor) {
  156|   249k|    c->i *= factor;
  157|   249k|    c->j *= factor;
  158|   249k|    c->k *= factor;
  159|   249k|}
h3Index.c:_ijkAdd:
  129|   223k|                           CoordIJK *sum) {
  130|   223k|    sum->i = h1->i + h2->i;
  131|   223k|    sum->j = h1->j + h2->j;
  132|   223k|    sum->k = h1->k + h2->k;
  133|   223k|}
h3Index.c:_upAp7r:
  494|  3.26k|static inline void _upAp7r(CoordIJK *ijk) {
  495|       |    // convert to CoordIJ
  496|  3.26k|    int i = ijk->i - ijk->k;
  497|  3.26k|    int j = ijk->j - ijk->k;
  498|       |
  499|  3.26k|    ijk->i = (int)lround((2 * i + j) * M_ONESEVENTH);
  ------------------
  |  |   54|  3.26k|#define M_ONESEVENTH 0.14285714285714285714285714285714285
  ------------------
  500|  3.26k|    ijk->j = (int)lround((3 * j - i) * M_ONESEVENTH);
  ------------------
  |  |   54|  3.26k|#define M_ONESEVENTH 0.14285714285714285714285714285714285
  ------------------
  501|  3.26k|    ijk->k = 0;
  502|  3.26k|    _ijkNormalize(ijk);
  503|  3.26k|}
h3Index.c:_downAp7r:
  534|  41.5k|static inline void _downAp7r(CoordIJK *ijk) {
  535|       |    // res r unit vectors in res r+1
  536|  41.5k|    CoordIJK iVec = {3, 1, 0};
  537|  41.5k|    CoordIJK jVec = {0, 3, 1};
  538|  41.5k|    CoordIJK kVec = {1, 0, 3};
  539|       |
  540|  41.5k|    _ijkScale(&iVec, ijk->i);
  541|  41.5k|    _ijkScale(&jVec, ijk->j);
  542|  41.5k|    _ijkScale(&kVec, ijk->k);
  543|       |
  544|  41.5k|    _ijkAdd(&iVec, &jVec, ijk);
  545|  41.5k|    _ijkAdd(ijk, &kVec, ijk);
  546|       |
  547|  41.5k|    _ijkNormalize(ijk);
  548|  41.5k|}
h3Index.c:_ijkNormalize:
  207|   143k|static inline void _ijkNormalize(CoordIJK *c) {
  208|       |    // remove any negative values
  209|   143k|    if (c->i < 0) {
  ------------------
  |  Branch (209:9): [True: 1.16k, False: 142k]
  ------------------
  210|  1.16k|        c->j -= c->i;
  211|  1.16k|        c->k -= c->i;
  212|  1.16k|        c->i = 0;
  213|  1.16k|    }
  214|       |
  215|   143k|    if (c->j < 0) {
  ------------------
  |  Branch (215:9): [True: 902, False: 142k]
  ------------------
  216|    902|        c->i -= c->j;
  217|    902|        c->k -= c->j;
  218|    902|        c->j = 0;
  219|    902|    }
  220|       |
  221|   143k|    if (c->k < 0) {
  ------------------
  |  Branch (221:9): [True: 0, False: 143k]
  ------------------
  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|   143k|    int min = c->i;
  229|   143k|    if (c->j < min) min = c->j;
  ------------------
  |  Branch (229:9): [True: 101k, False: 41.9k]
  ------------------
  230|   143k|    if (c->k < min) min = c->k;
  ------------------
  |  Branch (230:9): [True: 36.4k, False: 107k]
  ------------------
  231|   143k|    if (min > 0) {
  ------------------
  |  Branch (231:9): [True: 95.3k, False: 48.1k]
  ------------------
  232|  95.3k|        c->i -= min;
  233|  95.3k|        c->j -= min;
  234|  95.3k|        c->k -= min;
  235|  95.3k|    }
  236|   143k|}
h3Index.c:_neighbor:
  602|  77.6k|static inline void _neighbor(CoordIJK *ijk, Direction digit) {
  603|  77.6k|    if (digit > CENTER_DIGIT && digit < NUM_DIGITS) {
  ------------------
  |  Branch (603:9): [True: 60.8k, False: 16.8k]
  |  Branch (603:33): [True: 56.9k, False: 3.91k]
  ------------------
  604|  56.9k|        _ijkAdd(ijk, &UNIT_VECS[digit], ijk);
  605|  56.9k|        _ijkNormalize(ijk);
  606|  56.9k|    }
  607|  77.6k|}

faceijk.c:vec3LinComb:
   62|  1.74k|static inline Vec3d vec3LinComb(double a, Vec3d v1, double b, Vec3d v2) {
   63|  1.74k|    Vec3d out = {
   64|  1.74k|        .x = a * v1.x + b * v2.x,
   65|  1.74k|        .y = a * v1.y + b * v2.y,
   66|  1.74k|        .z = a * v1.z + b * v2.z,
   67|  1.74k|    };
   68|  1.74k|    return out;
   69|  1.74k|}
faceijk.c:vec3NormSq:
   84|  1.16k|static inline double vec3NormSq(Vec3d v) { return vec3Dot(v, v); }
faceijk.c:vec3Dot:
   80|  1.74k|static inline double vec3Dot(Vec3d v1, Vec3d v2) {
   81|  1.74k|    return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
   82|  1.74k|}
faceijk.c:vec3Cross:
   71|    582|static inline Vec3d vec3Cross(Vec3d v1, Vec3d v2) {
   72|    582|    Vec3d out = {
   73|    582|        .x = v1.y * v2.z - v1.z * v2.y,
   74|    582|        .y = v1.z * v2.x - v1.x * v2.z,
   75|    582|        .z = v1.x * v2.y - v1.y * v2.x,
   76|    582|    };
   77|    582|    return out;
   78|    582|}
faceijk.c:vec3Normalize:
   88|  1.16k|static inline void vec3Normalize(Vec3d *v) {
   89|  1.16k|    double norm = vec3Norm(*v);
   90|       |
   91|       |    // Norm can be zero either from true zero vector, or from squaring
   92|       |    // underflowing to zero.
   93|       |    // If the norm is nonzero, we normalize v using it.
   94|       |    // If the norm is zero, we set the vector to be exactly zero.
   95|  1.16k|    double s = 0.0;
   96|  1.16k|    if (norm > 0.0) {
  ------------------
  |  Branch (96:9): [True: 1.16k, False: 0]
  ------------------
   97|  1.16k|        s = 1.0 / norm;
   98|  1.16k|    }
   99|       |
  100|  1.16k|    v->x *= s;
  101|  1.16k|    v->y *= s;
  102|  1.16k|    v->z *= s;
  103|  1.16k|}
faceijk.c:vec3Norm:
   86|  1.16k|static inline double vec3Norm(Vec3d v) { return sqrt(vec3NormSq(v)); }
faceijk.c:vec3ToLatLng:
   54|    582|static inline LatLng vec3ToLatLng(Vec3d v) {
   55|    582|    LatLng out = {
   56|    582|        .lat = asin(v.z),
   57|    582|        .lng = atan2(v.y, v.x),
   58|    582|    };
   59|    582|    return out;
   60|    582|}

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

_isBaseCellPentagon:
  824|  54.8k|int _isBaseCellPentagon(int baseCell) {
  825|  54.8k|    if (baseCell < 0 || baseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |   81|  54.8k|#define NUM_BASE_CELLS 122
  ------------------
  |  Branch (825:9): [True: 0, False: 54.8k]
  |  Branch (825:25): [True: 42, False: 54.8k]
  ------------------
  826|       |        // Base cells less than zero can not be represented in an index
  827|     42|        return false;
  828|     42|    }
  829|  54.8k|    return baseCellData[baseCell].isPentagon;
  830|  54.8k|}
_isBaseCellPolarPentagon:
  834|  3.04k|bool _isBaseCellPolarPentagon(int baseCell) {
  835|  3.04k|    return baseCell == 4 || baseCell == 117;
  ------------------
  |  Branch (835:12): [True: 672, False: 2.37k]
  |  Branch (835:29): [True: 331, False: 2.04k]
  ------------------
  836|  3.04k|}
_baseCellToFaceIjk:
  866|  7.45k|void _baseCellToFaceIjk(int baseCell, FaceIJK *h) {
  867|  7.45k|    *h = baseCellData[baseCell].homeFijk;
  868|  7.45k|}
_baseCellToCCWrot60:
  877|  7.45k|int _baseCellToCCWrot60(int baseCell, int face) {
  878|  7.45k|    if (face < 0 || face >= NUM_ICOSA_FACES) return INVALID_ROTATIONS;
  ------------------
  |  |   79|  7.45k|#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.45k]
  |  Branch (878:21): [True: 0, False: 7.45k]
  ------------------
  879|  12.5k|    for (int i = 0; i < 3; i++) {
  ------------------
  |  Branch (879:21): [True: 12.5k, False: 0]
  ------------------
  880|  31.7k|        for (int j = 0; j < 3; j++) {
  ------------------
  |  Branch (880:25): [True: 26.6k, False: 5.07k]
  ------------------
  881|  87.2k|            for (int k = 0; k < 3; k++) {
  ------------------
  |  Branch (881:29): [True: 68.0k, False: 19.2k]
  ------------------
  882|  68.0k|                if (faceIjkBaseCells[face][i][j][k].baseCell == baseCell) {
  ------------------
  |  Branch (882:21): [True: 7.45k, False: 60.6k]
  ------------------
  883|  7.45k|                    return faceIjkBaseCells[face][i][j][k].ccwRot60;
  884|  7.45k|                }
  885|  68.0k|            }
  886|  26.6k|        }
  887|  12.5k|    }
  888|      0|    return INVALID_ROTATIONS;
  ------------------
  |  |   49|      0|#define INVALID_ROTATIONS -1
  ------------------
  889|  7.45k|}
_baseCellIsCwOffset:
  893|     82|bool _baseCellIsCwOffset(int baseCell, int testFace) {
  894|     82|    return baseCellData[baseCell].cwOffsetPent[0] == testFace ||
  ------------------
  |  Branch (894:12): [True: 44, False: 38]
  ------------------
  895|     38|           baseCellData[baseCell].cwOffsetPent[1] == testFace;
  ------------------
  |  Branch (895:12): [True: 38, False: 0]
  ------------------
  896|     82|}

_faceIjkPentToCellBoundary:
  532|     29|                                int length, CellBoundary *g) {
  533|     29|    int adjRes = res;
  534|     29|    FaceIJK centerIJK = *h;
  535|     29|    FaceIJK fijkVerts[NUM_PENT_VERTS];
  536|     29|    _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|     29|    int additionalIteration = length == NUM_PENT_VERTS ? 1 : 0;
  ------------------
  |  |   85|     29|#define NUM_PENT_VERTS 5
  ------------------
  |  Branch (540:31): [True: 0, False: 29]
  ------------------
  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|     29|    g->numVerts = 0;
  546|     29|    FaceIJK lastFijk = {0};
  547|     58|    for (int vert = start; vert < start + length + additionalIteration;
  ------------------
  |  Branch (547:28): [True: 29, False: 29]
  ------------------
  548|     29|         vert++) {
  549|     29|        int v = vert % NUM_PENT_VERTS;
  ------------------
  |  |   85|     29|#define NUM_PENT_VERTS 5
  ------------------
  550|       |
  551|     29|        FaceIJK fijk = fijkVerts[v];
  552|       |
  553|     29|        _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|     29|        if (isResolutionClassIII(res) && vert > start) {
  ------------------
  |  Branch (558:13): [True: 10, False: 19]
  |  Branch (558:42): [True: 0, False: 10]
  ------------------
  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|     29|        if (vert < start + NUM_PENT_VERTS) {
  ------------------
  |  |   85|     29|#define NUM_PENT_VERTS 5
  ------------------
  |  Branch (622:13): [True: 29, False: 0]
  ------------------
  623|     29|            Vec2d vec;
  624|     29|            _ijkToHex2d(&fijk.coord, &vec);
  625|     29|            Vec3d v3;
  626|     29|            _hex2dToVec3(&vec, fijk.face, adjRes, 1, &v3);
  627|     29|            g->verts[g->numVerts] = vec3ToLatLng(v3);
  628|     29|            g->numVerts++;
  629|     29|        }
  630|       |
  631|     29|        lastFijk = fijk;
  632|     29|    }
  633|     29|}
_faceIjkPentToVerts:
  642|     29|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|     29|    CoordIJK vertsCII[NUM_PENT_VERTS] = {
  648|     29|        {2, 1, 0},  // 0
  649|     29|        {1, 2, 0},  // 1
  650|     29|        {0, 2, 1},  // 2
  651|     29|        {0, 1, 2},  // 3
  652|     29|        {1, 0, 2},  // 4
  653|     29|    };
  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|     29|    CoordIJK vertsCIII[NUM_PENT_VERTS] = {
  660|     29|        {5, 4, 0},  // 0
  661|     29|        {1, 5, 0},  // 1
  662|     29|        {0, 5, 4},  // 2
  663|     29|        {0, 1, 5},  // 3
  664|     29|        {4, 0, 5},  // 4
  665|     29|    };
  666|       |
  667|       |    // get the correct set of substrate vertices for this resolution
  668|     29|    CoordIJK *verts;
  669|     29|    if (isResolutionClassIII(*res))
  ------------------
  |  Branch (669:9): [True: 10, False: 19]
  ------------------
  670|     10|        verts = vertsCIII;
  671|     19|    else
  672|     19|        verts = vertsCII;
  673|       |
  674|       |    // adjust the center point to be in an aperture 33r substrate grid
  675|       |    // these should be composed for speed
  676|     29|    _downAp3(&fijk->coord);
  677|     29|    _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|     29|    if (isResolutionClassIII(*res)) {
  ------------------
  |  Branch (681:9): [True: 10, False: 19]
  ------------------
  682|     10|        _downAp7r(&fijk->coord);
  683|     10|        *res += 1;
  684|     10|    }
  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|    174|    for (int v = 0; v < NUM_PENT_VERTS; v++) {
  ------------------
  |  |   85|    174|#define NUM_PENT_VERTS 5
  ------------------
  |  Branch (689:21): [True: 145, False: 29]
  ------------------
  690|    145|        fijkVerts[v].face = fijk->face;
  691|    145|        _ijkAdd(&fijk->coord, &verts[v], &fijkVerts[v].coord);
  692|    145|        _ijkNormalize(&fijkVerts[v].coord);
  693|    145|    }
  694|     29|}
_faceIjkToCellBoundary:
  707|    553|                            CellBoundary *g) {
  708|    553|    int adjRes = res;
  709|    553|    FaceIJK centerIJK = *h;
  710|    553|    FaceIJK fijkVerts[NUM_HEX_VERTS];
  711|    553|    _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|    553|    int additionalIteration = length == NUM_HEX_VERTS ? 1 : 0;
  ------------------
  |  |   83|    553|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (715:31): [True: 0, False: 553]
  ------------------
  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|    553|    g->numVerts = 0;
  721|    553|    int lastFace = -1;
  722|    553|    Overage lastOverage = NO_OVERAGE;
  723|  1.10k|    for (int vert = start; vert < start + length + additionalIteration;
  ------------------
  |  Branch (723:28): [True: 553, False: 553]
  ------------------
  724|    553|         vert++) {
  725|    553|        int v = vert % NUM_HEX_VERTS;
  ------------------
  |  |   83|    553|#define NUM_HEX_VERTS 6
  ------------------
  726|       |
  727|    553|        FaceIJK fijk = fijkVerts[v];
  728|       |
  729|    553|        const int pentLeading4 = 0;
  730|    553|        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|    553|        if (isResolutionClassIII(res) && vert > start &&
  ------------------
  |  Branch (741:13): [True: 408, False: 145]
  |  Branch (741:42): [True: 0, False: 408]
  ------------------
  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|    553|        if (vert < start + NUM_HEX_VERTS) {
  ------------------
  |  |   83|    553|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (798:13): [True: 553, False: 0]
  ------------------
  799|    553|            Vec2d vec;
  800|    553|            _ijkToHex2d(&fijk.coord, &vec);
  801|    553|            Vec3d v3;
  802|    553|            _hex2dToVec3(&vec, fijk.face, adjRes, 1, &v3);
  803|    553|            g->verts[g->numVerts] = vec3ToLatLng(v3);
  804|    553|            g->numVerts++;
  805|    553|        }
  806|       |
  807|    553|        lastFace = fijk.face;
  808|    553|        lastOverage = overage;
  809|    553|    }
  810|    553|}
_faceIjkToVerts:
  819|    553|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|    553|    CoordIJK vertsCII[NUM_HEX_VERTS] = {
  825|    553|        {2, 1, 0},  // 0
  826|    553|        {1, 2, 0},  // 1
  827|    553|        {0, 2, 1},  // 2
  828|    553|        {0, 1, 2},  // 3
  829|    553|        {1, 0, 2},  // 4
  830|    553|        {2, 0, 1}   // 5
  831|    553|    };
  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|    553|    CoordIJK vertsCIII[NUM_HEX_VERTS] = {
  838|    553|        {5, 4, 0},  // 0
  839|    553|        {1, 5, 0},  // 1
  840|    553|        {0, 5, 4},  // 2
  841|    553|        {0, 1, 5},  // 3
  842|    553|        {4, 0, 5},  // 4
  843|    553|        {5, 0, 1}   // 5
  844|    553|    };
  845|       |
  846|       |    // get the correct set of substrate vertices for this resolution
  847|    553|    CoordIJK *verts;
  848|    553|    if (isResolutionClassIII(*res))
  ------------------
  |  Branch (848:9): [True: 408, False: 145]
  ------------------
  849|    408|        verts = vertsCIII;
  850|    145|    else
  851|    145|        verts = vertsCII;
  852|       |
  853|       |    // adjust the center point to be in an aperture 33r substrate grid
  854|       |    // these should be composed for speed
  855|    553|    _downAp3(&fijk->coord);
  856|    553|    _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|    553|    if (isResolutionClassIII(*res)) {
  ------------------
  |  Branch (860:9): [True: 408, False: 145]
  ------------------
  861|    408|        _downAp7r(&fijk->coord);
  862|    408|        *res += 1;
  863|    408|    }
  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.87k|    for (int v = 0; v < NUM_HEX_VERTS; v++) {
  ------------------
  |  |   83|  3.87k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (868:21): [True: 3.31k, False: 553]
  ------------------
  869|  3.31k|        fijkVerts[v].face = fijk->face;
  870|  3.31k|        _ijkAdd(&fijk->coord, &verts[v], &fijkVerts[v].coord);
  871|  3.31k|        _ijkNormalize(&fijkVerts[v].coord);
  872|  3.31k|    }
  873|    553|}
_adjustOverageClassII:
  888|  12.9k|                              int substrate) {
  889|  12.9k|    Overage overage = NO_OVERAGE;
  890|       |
  891|  12.9k|    CoordIJK *ijk = &fijk->coord;
  892|       |
  893|       |    // get the maximum dimension value; scale if a substrate grid
  894|  12.9k|    int maxDim = maxDimByCIIres[res];
  895|  12.9k|    if (substrate) maxDim *= 3;
  ------------------
  |  Branch (895:9): [True: 604, False: 12.3k]
  ------------------
  896|       |
  897|       |    // check for overage
  898|  12.9k|    if (substrate && ijk->i + ijk->j + ijk->k == maxDim)  // on edge
  ------------------
  |  Branch (898:9): [True: 604, False: 12.3k]
  |  Branch (898:22): [True: 66, False: 538]
  ------------------
  899|     66|        overage = FACE_EDGE;
  900|  12.8k|    else if (ijk->i + ijk->j + ijk->k > maxDim)  // overage
  ------------------
  |  Branch (900:14): [True: 6.40k, False: 6.47k]
  ------------------
  901|  6.40k|    {
  902|  6.40k|        overage = NEW_FACE;
  903|       |
  904|  6.40k|        const FaceOrientIJK *fijkOrient;
  905|  6.40k|        if (ijk->k > 0) {
  ------------------
  |  Branch (905:13): [True: 4.36k, False: 2.03k]
  ------------------
  906|  4.36k|            if (ijk->j > 0)  // jk "quadrant"
  ------------------
  |  Branch (906:17): [True: 1.65k, False: 2.71k]
  ------------------
  907|  1.65k|                fijkOrient = &faceNeighbors[fijk->face][JK];
  ------------------
  |  |   57|  1.65k|#define JK 3
  ------------------
  908|  2.71k|            else  // ik "quadrant"
  909|  2.71k|            {
  910|  2.71k|                fijkOrient = &faceNeighbors[fijk->face][KI];
  ------------------
  |  |   55|  2.71k|#define KI 2
  ------------------
  911|       |
  912|       |                // adjust for the pentagonal missing sequence
  913|  2.71k|                if (pentLeading4) {
  ------------------
  |  Branch (913:21): [True: 565, False: 2.14k]
  ------------------
  914|       |                    // translate origin to center of pentagon
  915|    565|                    CoordIJK origin;
  916|    565|                    _setIJK(&origin, maxDim, 0, 0);
  917|    565|                    CoordIJK tmp;
  918|    565|                    _ijkSub(ijk, &origin, &tmp);
  919|       |                    // rotate to adjust for the missing sequence
  920|    565|                    _ijkRotate60cw(&tmp);
  921|       |                    // translate the origin back to the center of the triangle
  922|    565|                    _ijkAdd(&tmp, &origin, ijk);
  923|    565|                }
  924|  2.71k|            }
  925|  4.36k|        } else  // ij "quadrant"
  926|  2.03k|            fijkOrient = &faceNeighbors[fijk->face][IJ];
  ------------------
  |  |   53|  2.03k|#define IJ 1
  ------------------
  927|       |
  928|  6.40k|        fijk->face = fijkOrient->face;
  929|       |
  930|       |        // rotate and translate for adjacent face
  931|  26.2k|        for (int i = 0; i < fijkOrient->ccwRot60; i++) _ijkRotate60ccw(ijk);
  ------------------
  |  Branch (931:25): [True: 19.8k, False: 6.40k]
  ------------------
  932|       |
  933|  6.40k|        CoordIJK transVec = fijkOrient->translate;
  934|  6.40k|        int unitScale = unitScaleByCIIres[res];
  935|  6.40k|        if (substrate) unitScale *= 3;
  ------------------
  |  Branch (935:13): [True: 58, False: 6.34k]
  ------------------
  936|  6.40k|        _ijkScale(&transVec, unitScale);
  937|  6.40k|        _ijkAdd(ijk, &transVec, ijk);
  938|  6.40k|        _ijkNormalize(ijk);
  939|       |
  940|       |        // overage points on pentagon boundaries can end up on edges
  941|  6.40k|        if (substrate && ijk->i + ijk->j + ijk->k == maxDim)  // on edge
  ------------------
  |  Branch (941:13): [True: 58, False: 6.34k]
  |  Branch (941:26): [True: 13, False: 45]
  ------------------
  942|     13|            overage = FACE_EDGE;
  943|  6.40k|    }
  944|       |
  945|  12.9k|    return overage;
  946|  12.9k|}
_adjustPentVertOverage:
  956|     29|Overage _adjustPentVertOverage(FaceIJK *fijk, int res) {
  957|     29|    int pentLeading4 = 0;
  958|     29|    Overage overage;
  959|     51|    do {
  960|     51|        overage = _adjustOverageClassII(fijk, res, pentLeading4, 1);
  961|     51|    } while (overage == NEW_FACE);
  ------------------
  |  Branch (961:14): [True: 22, False: 29]
  ------------------
  962|     29|    return overage;
  963|     29|}
faceijk.c:_vec3TangentBasis:
  375|    582|static inline void _vec3TangentBasis(Vec3d p, Vec3d *north, Vec3d *east) {
  376|    582|    Vec3d northPole = {0.0, 0.0, 1.0};
  377|    582|    *north = vec3LinComb(1.0, northPole, -vec3Dot(northPole, p), p);
  378|    582|    vec3Normalize(north);
  379|    582|    *east = vec3Cross(*north, p);
  380|    582|}
faceijk.c:_hex2dToVec3:
  459|    582|                         Vec3d *v3) {
  460|       |    // calculate (r, theta) in hex2d
  461|    582|    double r = _v2dMag(v);
  462|       |
  463|    582|    if (r < EPSILON) {
  ------------------
  |  |   42|    582|#define EPSILON 0.0000000000000001
  ------------------
  |  Branch (463:9): [True: 0, False: 582]
  ------------------
  464|      0|        *v3 = faceCenterPoint[face];
  465|      0|        return;
  466|      0|    }
  467|       |
  468|    582|    double theta = atan2(v->y, v->x);
  469|       |
  470|       |    // scale for current resolution length u
  471|  6.62k|    for (int i = 0; i < res; i++) r *= M_RSQRT7;
  ------------------
  |  |   37|  6.62k|#define M_RSQRT7 0.37796447300922722721451653623418006081576
  ------------------
  |  Branch (471:21): [True: 6.04k, False: 582]
  ------------------
  472|       |
  473|       |    // scale accordingly if this is a substrate grid
  474|    582|    if (substrate) {
  ------------------
  |  Branch (474:9): [True: 582, False: 0]
  ------------------
  475|    582|        r *= M_ONETHIRD;
  ------------------
  |  |   51|    582|#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|    582|        if (NEVER(isResolutionClassIII(res))) {
  ------------------
  |  |  119|    582|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 582]
  |  |  |  Branch (119:19): [True: 0, False: 582]
  |  |  ------------------
  ------------------
  |  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|    582|    }
  483|       |
  484|    582|    r *= RES0_U_GNOMONIC;
  ------------------
  |  |   72|    582|#define RES0_U_GNOMONIC 0.38196601125010500003
  ------------------
  485|       |
  486|       |    // perform inverse gnomonic scaling of r
  487|    582|    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|    582|    if (!substrate && isResolutionClassIII(res))
  ------------------
  |  Branch (491:9): [True: 0, False: 582]
  |  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|    582|    theta = _posAngleRads(faceAxesAzRadsCII[face][0] - theta);
  496|       |
  497|       |    // now find the point at (r,theta) from the face center
  498|    582|    Vec3d northDir, eastDir;
  499|    582|    _vec3TangentBasis(faceCenterPoint[face], &northDir, &eastDir);
  500|       |
  501|    582|    Vec3d dir = vec3LinComb(cos(theta), northDir, sin(theta), eastDir);
  502|       |
  503|    582|    *v3 = vec3LinComb(cos(r), faceCenterPoint[face], sin(r), dir);
  504|    582|    vec3Normalize(v3);
  505|    582|}

getBaseCellNumber:
   98|  7.45k|int H3_EXPORT(getBaseCellNumber)(H3Index h) { return H3_GET_BASE_CELL(h); }
  ------------------
  |  |  118|  7.45k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  7.45k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  7.45k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  7.45k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
isValidCell:
  343|    240|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|    240|    if (!_hasGoodTopBits(h)) return false;
  ------------------
  |  Branch (365:9): [True: 2, False: 238]
  ------------------
  366|       |
  367|       |    // No need to check resolution; any 4 bits give a valid resolution.
  368|    238|    const int res = H3_GET_RESOLUTION(h);
  ------------------
  |  |  129|    238|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|    238|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|    238|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|    238|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  369|       |
  370|       |    // Get base cell number and check that it is valid.
  371|    238|    const int bc = H3_GET_BASE_CELL(h);
  ------------------
  |  |  118|    238|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|    238|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|    238|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|    238|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  372|    238|    if (bc >= NUM_BASE_CELLS) return false;
  ------------------
  |  |   81|    238|#define NUM_BASE_CELLS 122
  ------------------
  |  Branch (372:9): [True: 2, False: 236]
  ------------------
  373|       |
  374|    236|    if (_hasAny7UptoRes(h, res)) return false;
  ------------------
  |  Branch (374:9): [True: 29, False: 207]
  ------------------
  375|    207|    if (!_hasAll7AfterRes(h, res)) return false;
  ------------------
  |  Branch (375:9): [True: 62, False: 145]
  ------------------
  376|    145|    if (_hasDeletedSubsequence(h, bc)) return false;
  ------------------
  |  Branch (376:9): [True: 8, False: 137]
  ------------------
  377|       |
  378|       |    // If no disqualifications were identified, the index is a valid H3 cell.
  379|    137|    return true;
  380|    145|}
isPentagon:
  841|  14.6k|int H3_EXPORT(isPentagon)(H3Index h) {
  842|  14.6k|    return _isBaseCellPentagon(H3_GET_BASE_CELL(h)) &&
  ------------------
  |  |  118|  14.6k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  14.6k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  14.6k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  14.6k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  |  Branch (842:12): [True: 6.84k, False: 7.82k]
  ------------------
  843|  6.84k|           !_h3LeadingNonZeroDigit(h);
  ------------------
  |  Branch (843:12): [True: 740, False: 6.10k]
  ------------------
  844|  14.6k|}
_h3LeadingNonZeroDigit:
  851|  31.1k|Direction _h3LeadingNonZeroDigit(H3Index h) {
  852|  94.3k|    for (int r = 1; r <= H3_GET_RESOLUTION(h); r++)
  ------------------
  |  |  129|  94.3k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  94.3k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  94.3k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  94.3k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (852:21): [True: 90.7k, False: 3.61k]
  ------------------
  853|  90.7k|        if (H3_GET_INDEX_DIGIT(h, r)) return H3_GET_INDEX_DIGIT(h, r);
  ------------------
  |  |  141|  90.7k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  90.7k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  90.7k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  |  Branch (141:5): [True: 27.5k, False: 63.1k]
  |  |  ------------------
  |  |  142|  90.7k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  90.7k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
                      if (H3_GET_INDEX_DIGIT(h, r)) return H3_GET_INDEX_DIGIT(h, r);
  ------------------
  |  |  141|  27.5k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  27.5k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  27.5k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  27.5k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  27.5k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  854|       |
  855|       |    // if we're here it's all 0's
  856|  3.61k|    return CENTER_DIGIT;
  857|  31.1k|}
_h3RotatePent60ccw:
  863|    628|H3Index _h3RotatePent60ccw(H3Index h) {
  864|       |    // rotate in place; skips any leading 1 digits (k-axis)
  865|       |
  866|    628|    int foundFirstNonZeroDigit = 0;
  867|  4.50k|    for (int r = 1, res = H3_GET_RESOLUTION(h); r <= res; r++) {
  ------------------
  |  |  129|    628|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|    628|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|    628|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|    628|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (867:49): [True: 3.88k, False: 628]
  ------------------
  868|       |        // rotate this digit
  869|  3.88k|        H3_SET_INDEX_DIGIT(h, r, _rotate60ccw(H3_GET_INDEX_DIGIT(h, r)));
  ------------------
  |  |  162|  3.88k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  3.88k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  3.88k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  3.88k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  3.88k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  3.88k|            (((uint64_t)(digit))                                            \
  |  |  165|  3.88k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  3.88k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  3.88k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  ------------------
  870|       |
  871|       |        // look for the first non-zero digit so we
  872|       |        // can adjust for deleted k-axes sequence
  873|       |        // if necessary
  874|  3.88k|        if (!foundFirstNonZeroDigit && H3_GET_INDEX_DIGIT(h, r) != 0) {
  ------------------
  |  |  141|    511|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|    511|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|    511|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|    511|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|    511|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  |  Branch (874:13): [True: 511, False: 3.37k]
  |  Branch (874:40): [True: 511, False: 0]
  ------------------
  875|    511|            foundFirstNonZeroDigit = 1;
  876|       |
  877|       |            // adjust for deleted k-axes sequence
  878|    511|            if (_h3LeadingNonZeroDigit(h) == K_AXES_DIGIT)
  ------------------
  |  Branch (878:17): [True: 198, False: 313]
  ------------------
  879|    198|                h = _h3Rotate60ccw(h);
  880|    511|        }
  881|  3.88k|    }
  882|    628|    return h;
  883|    628|}
_h3Rotate60ccw:
  914|  2.14k|H3Index _h3Rotate60ccw(H3Index h) {
  915|  8.47k|    for (int r = 1, res = H3_GET_RESOLUTION(h); r <= res; r++) {
  ------------------
  |  |  129|  2.14k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  2.14k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  2.14k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  2.14k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (915:49): [True: 6.33k, False: 2.14k]
  ------------------
  916|  6.33k|        Direction oldDigit = H3_GET_INDEX_DIGIT(h, r);
  ------------------
  |  |  141|  6.33k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  6.33k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  6.33k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  6.33k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  6.33k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  917|  6.33k|        H3_SET_INDEX_DIGIT(h, r, _rotate60ccw(oldDigit));
  ------------------
  |  |  162|  6.33k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  6.33k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  6.33k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  6.33k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  6.33k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  6.33k|            (((uint64_t)(digit))                                            \
  |  |  165|  6.33k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  6.33k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  6.33k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  ------------------
  918|  6.33k|    }
  919|       |
  920|  2.14k|    return h;
  921|  2.14k|}
_h3Rotate60cw:
  927|    844|H3Index _h3Rotate60cw(H3Index h) {
  928|  9.50k|    for (int r = 1, res = H3_GET_RESOLUTION(h); r <= res; r++) {
  ------------------
  |  |  129|    844|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|    844|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|    844|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|    844|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (928:49): [True: 8.66k, False: 844]
  ------------------
  929|  8.66k|        H3_SET_INDEX_DIGIT(h, r, _rotate60cw(H3_GET_INDEX_DIGIT(h, r)));
  ------------------
  |  |  162|  8.66k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  8.66k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  8.66k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  8.66k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  8.66k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  8.66k|            (((uint64_t)(digit))                                            \
  |  |  165|  8.66k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  8.66k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  8.66k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  ------------------
  930|  8.66k|    }
  931|       |
  932|    844|    return h;
  933|    844|}
_h3ToFaceIjkWithInitializedFijk:
 1086|  8.03k|int _h3ToFaceIjkWithInitializedFijk(H3Index h, FaceIJK *fijk) {
 1087|  8.03k|    CoordIJK *ijk = &fijk->coord;
 1088|  8.03k|    int res = H3_GET_RESOLUTION(h);
  ------------------
  |  |  129|  8.03k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  8.03k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  8.03k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  8.03k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
 1089|       |
 1090|       |    // center base cell hierarchy is entirely on this face
 1091|  8.03k|    int possibleOverage = 1;
 1092|  8.03k|    if (!_isBaseCellPentagon(H3_GET_BASE_CELL(h)) &&
  ------------------
  |  |  118|  8.03k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  8.03k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  8.03k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  8.03k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  |  Branch (1092:9): [True: 4.42k, False: 3.61k]
  ------------------
 1093|  4.42k|        (res == 0 ||
  ------------------
  |  Branch (1093:10): [True: 737, False: 3.68k]
  ------------------
 1094|  3.68k|         (fijk->coord.i == 0 && fijk->coord.j == 0 && fijk->coord.k == 0)))
  ------------------
  |  Branch (1094:11): [True: 2.05k, False: 1.63k]
  |  Branch (1094:33): [True: 893, False: 1.15k]
  |  Branch (1094:55): [True: 278, False: 615]
  ------------------
 1095|  1.01k|        possibleOverage = 0;
 1096|       |
 1097|  85.7k|    for (int r = 1; r <= res; r++) {
  ------------------
  |  Branch (1097:21): [True: 77.6k, False: 8.03k]
  ------------------
 1098|  77.6k|        if (isResolutionClassIII(r)) {
  ------------------
  |  Branch (1098:13): [True: 41.7k, False: 35.9k]
  ------------------
 1099|       |            // Class III == rotate ccw
 1100|  41.7k|            _downAp7(ijk);
 1101|  41.7k|        } else {
 1102|       |            // Class II == rotate cw
 1103|  35.9k|            _downAp7r(ijk);
 1104|  35.9k|        }
 1105|       |
 1106|  77.6k|        _neighbor(ijk, H3_GET_INDEX_DIGIT(h, r));
  ------------------
  |  |  141|  77.6k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  77.6k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  77.6k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  77.6k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  77.6k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
 1107|  77.6k|    }
 1108|       |
 1109|  8.03k|    return possibleOverage;
 1110|  8.03k|}
_h3ToFaceIjk:
 1117|  8.05k|H3Error _h3ToFaceIjk(H3Index h, FaceIJK *fijk) {
 1118|  8.05k|    int baseCell = H3_GET_BASE_CELL(h);
  ------------------
  |  |  118|  8.05k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  8.05k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  8.05k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  8.05k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
 1119|  8.05k|    if (NEVER(baseCell < 0) || baseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |  119|  16.1k|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 8.05k]
  |  |  |  Branch (119:19): [True: 0, False: 8.05k]
  |  |  ------------------
  ------------------
                  if (NEVER(baseCell < 0) || baseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |   81|  8.05k|#define NUM_BASE_CELLS 122
  ------------------
  |  Branch (1119:9): [Folded, False: 0]
  |  Branch (1119:9): [Folded, False: 0]
  |  Branch (1119:32): [True: 13, False: 8.03k]
  ------------------
 1120|       |        // Base cells less than zero can not be represented in an index
 1121|       |        // To prevent reading uninitialized memory, we zero the output.
 1122|     13|        fijk->face = 0;
 1123|     13|        fijk->coord.i = fijk->coord.j = fijk->coord.k = 0;
 1124|     13|        return E_CELL_INVALID;
 1125|     13|    }
 1126|       |    // adjust for the pentagonal missing sequence; all of sub-sequence 5 needs
 1127|       |    // to be adjusted (and some of sub-sequence 4 below)
 1128|  8.03k|    if (_isBaseCellPentagon(baseCell) && _h3LeadingNonZeroDigit(h) == 5)
  ------------------
  |  Branch (1128:9): [True: 3.61k, False: 4.42k]
  |  Branch (1128:42): [True: 654, False: 2.96k]
  ------------------
 1129|    654|        h = _h3Rotate60cw(h);
 1130|       |
 1131|       |    // start with the "home" face and ijk+ coordinates for the base cell of c
 1132|  8.03k|    *fijk = baseCellData[baseCell].homeFijk;
 1133|  8.03k|    if (!_h3ToFaceIjkWithInitializedFijk(h, fijk))
  ------------------
  |  Branch (1133:9): [True: 1.01k, False: 7.02k]
  ------------------
 1134|  1.01k|        return E_SUCCESS;  // no overage is possible; h lies on this face
 1135|       |
 1136|       |    // if we're here we have the potential for an "overage"; i.e., it is
 1137|       |    // possible that c lies on an adjacent face
 1138|       |
 1139|  7.02k|    CoordIJK origIJK = fijk->coord;
 1140|       |
 1141|       |    // if we're in Class III, drop into the next finer Class II grid
 1142|  7.02k|    int res = H3_GET_RESOLUTION(h);
  ------------------
  |  |  129|  7.02k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  7.02k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  7.02k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  7.02k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
 1143|  7.02k|    if (isResolutionClassIII(res)) {
  ------------------
  |  Branch (1143:9): [True: 5.61k, False: 1.40k]
  ------------------
 1144|       |        // Class III
 1145|  5.61k|        _downAp7r(&fijk->coord);
 1146|  5.61k|        res++;
 1147|  5.61k|    }
 1148|       |
 1149|       |    // adjust for overage if needed
 1150|       |    // a pentagon base cell with a leading 4 digit requires special handling
 1151|  7.02k|    int pentLeading4 =
 1152|  7.02k|        (_isBaseCellPentagon(baseCell) && _h3LeadingNonZeroDigit(h) == 4);
  ------------------
  |  Branch (1152:10): [True: 3.61k, False: 3.40k]
  |  Branch (1152:43): [True: 1.17k, False: 2.44k]
  ------------------
 1153|  7.02k|    if (_adjustOverageClassII(fijk, res, pentLeading4, 0) != NO_OVERAGE) {
  ------------------
  |  Branch (1153:9): [True: 3.88k, False: 3.13k]
  ------------------
 1154|       |        // if the base cell is a pentagon we have the potential for secondary
 1155|       |        // overages
 1156|  3.88k|        if (_isBaseCellPentagon(baseCell)) {
  ------------------
  |  Branch (1156:13): [True: 2.85k, False: 1.02k]
  ------------------
 1157|  5.31k|            while (_adjustOverageClassII(fijk, res, 0, 0) != NO_OVERAGE)
  ------------------
  |  Branch (1157:20): [True: 2.45k, False: 2.85k]
  ------------------
 1158|  2.45k|                continue;
 1159|  2.85k|        }
 1160|       |
 1161|  3.88k|        if (res != H3_GET_RESOLUTION(h)) _upAp7r(&fijk->coord);
  ------------------
  |  |  129|  3.88k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  3.88k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  3.88k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  3.88k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (1161:13): [True: 3.26k, False: 624]
  ------------------
 1162|  3.88k|    } else if (res != H3_GET_RESOLUTION(h)) {
  ------------------
  |  |  129|  3.13k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  3.13k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  3.13k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  3.13k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (1162:16): [True: 2.35k, False: 785]
  ------------------
 1163|  2.35k|        fijk->coord = origIJK;
 1164|  2.35k|    }
 1165|  7.02k|    return E_SUCCESS;
 1166|  8.03k|}
isResolutionClassIII:
 1355|   102k|int isResolutionClassIII(int res) { return res % 2; }
h3Index.c:_hasGoodTopBits:
  216|    240|static inline bool _hasGoodTopBits(H3Index h) {
  217|    240|    h >>= (64 - 8);
  218|    240|    return h == 0b00001000;
  219|    240|}
h3Index.c:_hasAny7UptoRes:
  264|    236|static inline bool _hasAny7UptoRes(H3Index h, int res) {
  265|    236|    const uint64_t MHI = 0b100100100100100100100100100100100100100100100;
  266|    236|    const uint64_t MLO = MHI >> 2;
  267|       |
  268|    236|    int shift = 3 * (15 - res);
  269|    236|    h >>= shift;
  270|    236|    h <<= shift;
  271|    236|    h = (h & MHI & (~h - MLO));
  272|       |
  273|    236|    return h != 0;
  274|    236|}
h3Index.c:_hasAll7AfterRes:
  280|    207|static inline bool _hasAll7AfterRes(H3Index h, int res) {
  281|       |    // NOTE: res check is needed because we can't shift by 64
  282|    207|    if (res < 15) {
  ------------------
  |  Branch (282:9): [True: 103, False: 104]
  ------------------
  283|    103|        int shift = 19 + 3 * res;
  284|       |
  285|    103|        h = ~h;
  286|    103|        h <<= shift;
  287|    103|        h >>= shift;
  288|       |
  289|    103|        return h == 0;
  290|    103|    }
  291|    104|    return true;
  292|    207|}
h3Index.c:_hasDeletedSubsequence:
  327|    145|static inline bool _hasDeletedSubsequence(H3Index h, int base_cell) {
  328|    145|    if (isBaseCellPentagonArr[base_cell]) {
  ------------------
  |  Branch (328:9): [True: 90, False: 55]
  ------------------
  329|     90|        h <<= 19;
  330|     90|        h >>= 19;
  331|       |
  332|     90|        if (h == 0) return false;  // all zeros: res 15 pentagon
  ------------------
  |  Branch (332:13): [True: 2, False: 88]
  ------------------
  333|     88|        return _firstOneIndex(h) % 3 == 0;
  334|     90|    }
  335|     55|    return false;
  336|    145|}
h3Index.c:_firstOneIndex:
  300|     88|static inline int _firstOneIndex(H3Index h) {
  301|     88|#if defined(__GNUC__) || defined(__clang__)
  302|     88|    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|     88|}

_posAngleRads:
   36|    582|double _posAngleRads(double rads) {
   37|    582|    double tmp = ((rads < 0.0) ? rads + M_2PI : rads);
  ------------------
  |  |   34|     44|#define M_2PI 6.28318530717958647692528676655900576839433
  ------------------
  |  Branch (37:19): [True: 44, False: 538]
  ------------------
   38|    582|    if (rads >= M_2PI) tmp -= M_2PI;
  ------------------
  |  |   34|    582|#define M_2PI 6.28318530717958647692528676655900576839433
  ------------------
                  if (rads >= M_2PI) tmp -= M_2PI;
  ------------------
  |  |   34|     47|#define M_2PI 6.28318530717958647692528676655900576839433
  ------------------
  |  Branch (38:9): [True: 47, False: 535]
  ------------------
   39|    582|    return tmp;
   40|    582|}

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

vertexNumForDirection:
  130|  2.16k|int vertexNumForDirection(const H3Index origin, const Direction direction) {
  131|  2.16k|    int isPent = H3_EXPORT(isPentagon)(origin);
  ------------------
  |  |   36|  2.16k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  2.16k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  2.16k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  132|       |    // Check for invalid directions
  133|  2.16k|    if (direction == CENTER_DIGIT || direction >= INVALID_DIGIT ||
  ------------------
  |  Branch (133:9): [True: 0, False: 2.16k]
  |  Branch (133:38): [True: 23, False: 2.14k]
  ------------------
  134|  2.14k|        (isPent && direction == K_AXES_DIGIT))
  ------------------
  |  Branch (134:10): [True: 116, False: 2.02k]
  |  Branch (134:20): [True: 0, False: 116]
  ------------------
  135|     23|        return INVALID_VERTEX_NUM;
  ------------------
  |  |   36|     23|#define INVALID_VERTEX_NUM -1
  ------------------
  136|       |
  137|       |    // Determine the vertex rotations for this cell
  138|  2.14k|    int rotations;
  139|  2.14k|    H3Error err = vertexRotations(origin, &rotations);
  140|  2.14k|    if (err) {
  ------------------
  |  Branch (140:9): [True: 0, False: 2.14k]
  ------------------
  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.14k|    if (isPent) {
  ------------------
  |  Branch (145:9): [True: 116, False: 2.02k]
  ------------------
  146|    116|        return (directionToVertexNumPent[direction] + NUM_PENT_VERTS -
  ------------------
  |  |   85|    116|#define NUM_PENT_VERTS 5
  ------------------
  147|    116|                rotations) %
  148|    116|               NUM_PENT_VERTS;
  ------------------
  |  |   85|    116|#define NUM_PENT_VERTS 5
  ------------------
  149|  2.02k|    } else {
  150|  2.02k|        return (directionToVertexNumHex[direction] + NUM_HEX_VERTS -
  ------------------
  |  |   83|  2.02k|#define NUM_HEX_VERTS 6
  ------------------
  151|  2.02k|                rotations) %
  152|  2.02k|               NUM_HEX_VERTS;
  ------------------
  |  |   83|  2.02k|#define NUM_HEX_VERTS 6
  ------------------
  153|  2.02k|    }
  154|  2.14k|}
directionForVertexNum:
  173|  5.32k|Direction directionForVertexNum(const H3Index origin, const int vertexNum) {
  174|  5.32k|    int isPent = H3_EXPORT(isPentagon)(origin);
  ------------------
  |  |   36|  5.32k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  5.32k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  5.32k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  175|       |    // Check for invalid vertexes
  176|  5.32k|    if (vertexNum < 0 ||
  ------------------
  |  Branch (176:9): [True: 0, False: 5.32k]
  ------------------
  177|  5.32k|        vertexNum > (isPent ? NUM_PENT_VERTS : NUM_HEX_VERTS) - 1)
  ------------------
  |  |   85|     86|#define NUM_PENT_VERTS 5
  ------------------
                      vertexNum > (isPent ? NUM_PENT_VERTS : NUM_HEX_VERTS) - 1)
  ------------------
  |  |   83|  5.23k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (177:9): [True: 0, False: 5.32k]
  |  Branch (177:22): [True: 86, False: 5.23k]
  ------------------
  178|      0|        return INVALID_DIGIT;
  179|       |
  180|       |    // Determine the vertex rotations for this cell
  181|  5.32k|    int rotations;
  182|  5.32k|    H3Error err = vertexRotations(origin, &rotations);
  183|  5.32k|    if (err) {
  ------------------
  |  Branch (183:9): [True: 6, False: 5.31k]
  ------------------
  184|      6|        return INVALID_DIGIT;
  185|      6|    }
  186|       |
  187|       |    // Find the appropriate direction, rotating CW if necessary
  188|  5.31k|    return isPent ? vertexNumToDirectionPent[(vertexNum + rotations) %
  ------------------
  |  Branch (188:12): [True: 86, False: 5.22k]
  ------------------
  189|     86|                                             NUM_PENT_VERTS]
  ------------------
  |  |   85|     86|#define NUM_PENT_VERTS 5
  ------------------
  190|  5.31k|                  : vertexNumToDirectionHex[(vertexNum + rotations) %
  191|  5.22k|                                            NUM_HEX_VERTS];
  ------------------
  |  |   83|  5.22k|#define NUM_HEX_VERTS 6
  ------------------
  192|  5.32k|}
cellToVertex:
  212|  3.70k|H3Error H3_EXPORT(cellToVertex)(H3Index cell, int vertexNum, H3Index *out) {
  213|  3.70k|    int cellIsPentagon = H3_EXPORT(isPentagon)(cell);
  ------------------
  |  |   36|  3.70k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  3.70k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  3.70k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  214|  3.70k|    int cellNumVerts = cellIsPentagon ? NUM_PENT_VERTS : NUM_HEX_VERTS;
  ------------------
  |  |   85|    179|#define NUM_PENT_VERTS 5
  ------------------
                  int cellNumVerts = cellIsPentagon ? NUM_PENT_VERTS : NUM_HEX_VERTS;
  ------------------
  |  |   83|  3.52k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (214:24): [True: 179, False: 3.52k]
  ------------------
  215|  3.70k|    int res = H3_GET_RESOLUTION(cell);
  ------------------
  |  |  129|  3.70k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  3.70k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  3.70k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  3.70k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  216|       |
  217|       |    // Check for invalid vertexes
  218|  3.70k|    if (vertexNum < 0 || vertexNum > cellNumVerts - 1) return E_DOMAIN;
  ------------------
  |  Branch (218:9): [True: 159, False: 3.54k]
  |  Branch (218:26): [True: 288, False: 3.25k]
  ------------------
  219|       |
  220|       |    // Default the owner and vertex number to the input cell
  221|  3.25k|    H3Index owner = cell;
  222|  3.25k|    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.25k|    if (res == 0 || H3_GET_INDEX_DIGIT(cell, res) != CENTER_DIGIT) {
  ------------------
  |  |  141|  2.93k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  2.93k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  2.93k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  2.93k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  2.93k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  |  Branch (229:9): [True: 329, False: 2.93k]
  |  Branch (229:21): [True: 2.58k, False: 347]
  ------------------
  230|       |        // Get the left neighbor of the vertex, with its rotations
  231|  2.91k|        Direction left = directionForVertexNum(cell, vertexNum);
  232|  2.91k|        if (left == INVALID_DIGIT) return E_FAILED;
  ------------------
  |  Branch (232:13): [True: 6, False: 2.90k]
  ------------------
  233|  2.90k|        int lRotations = 0;
  234|  2.90k|        H3Index leftNeighbor;
  235|  2.90k|        H3Error leftNeighborError =
  236|  2.90k|            h3NeighborRotations(cell, left, &lRotations, &leftNeighbor);
  237|  2.90k|        if (leftNeighborError) return leftNeighborError;
  ------------------
  |  Branch (237:13): [True: 99, False: 2.80k]
  ------------------
  238|       |        // Set to owner if lowest index
  239|  2.80k|        if (leftNeighbor < owner) owner = leftNeighbor;
  ------------------
  |  Branch (239:13): [True: 1.68k, False: 1.12k]
  ------------------
  240|       |
  241|       |        // As above, skip the right neighbor if the left is known lowest
  242|  2.80k|        if (res == 0 || H3_GET_INDEX_DIGIT(leftNeighbor, res) != CENTER_DIGIT) {
  ------------------
  |  |  141|  2.48k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  2.48k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  2.48k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  2.48k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  2.48k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  |  Branch (242:13): [True: 326, False: 2.48k]
  |  Branch (242:25): [True: 2.08k, False: 399]
  ------------------
  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.40k|            Direction right = directionForVertexNum(
  246|  2.40k|                cell, (vertexNum - 1 + cellNumVerts) % cellNumVerts);
  247|       |            // This case should be unreachable; invalid verts fail earlier
  248|  2.40k|            if (NEVER(right == INVALID_DIGIT)) return E_FAILED;
  ------------------
  |  |  119|  2.40k|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 2.40k]
  |  |  |  Branch (119:19): [True: 0, False: 2.40k]
  |  |  ------------------
  ------------------
  |  Branch (248:17): [Folded, False: 0]
  |  Branch (248:17): [Folded, False: 0]
  ------------------
  249|  2.40k|            int rRotations = 0;
  250|  2.40k|            H3Index rightNeighbor;
  251|  2.40k|            H3Error rightNeighborError =
  252|  2.40k|                h3NeighborRotations(cell, right, &rRotations, &rightNeighbor);
  253|  2.40k|            if (rightNeighborError) return rightNeighborError;
  ------------------
  |  Branch (253:17): [True: 28, False: 2.38k]
  ------------------
  254|       |            // Set to owner if lowest index
  255|  2.38k|            if (rightNeighbor < owner) {
  ------------------
  |  Branch (255:17): [True: 1.09k, False: 1.28k]
  ------------------
  256|  1.09k|                owner = rightNeighbor;
  257|  1.09k|                Direction dir =
  258|  1.09k|                    H3_EXPORT(isPentagon)(owner)
  ------------------
  |  |   36|  1.09k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  1.09k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  1.09k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (258:21): [True: 80, False: 1.01k]
  ------------------
  259|  1.09k|                        ? directionForNeighbor(owner, cell)
  260|  1.09k|                        : DIRECTIONS[(revNeighborDirectionsHex[right] +
  261|  1.01k|                                      rRotations) %
  262|  1.01k|                                     NUM_HEX_VERTS];
  ------------------
  |  |   83|  1.01k|#define NUM_HEX_VERTS 6
  ------------------
  263|  1.09k|                ownerVertexNum = vertexNumForDirection(owner, dir);
  264|  1.09k|            }
  265|  2.38k|        }
  266|       |
  267|       |        // Determine the vertex number for the left neighbor
  268|  2.77k|        if (owner == leftNeighbor) {
  ------------------
  |  Branch (268:13): [True: 1.07k, False: 1.70k]
  ------------------
  269|  1.07k|            int ownerIsPentagon = H3_EXPORT(isPentagon)(owner);
  ------------------
  |  |   36|  1.07k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  1.07k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  1.07k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  270|  1.07k|            Direction dir =
  271|  1.07k|                ownerIsPentagon
  ------------------
  |  Branch (271:17): [True: 59, False: 1.01k]
  ------------------
  272|  1.07k|                    ? directionForNeighbor(owner, cell)
  273|  1.07k|                    : DIRECTIONS[(revNeighborDirectionsHex[left] + lRotations) %
  274|  1.01k|                                 NUM_HEX_VERTS];
  ------------------
  |  |   83|  1.01k|#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.07k|            ownerVertexNum = vertexNumForDirection(owner, dir) + 1;
  279|  1.07k|            if (ownerVertexNum == NUM_HEX_VERTS ||
  ------------------
  |  |   83|  2.15k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (279:17): [True: 169, False: 906]
  ------------------
  280|    906|                (ownerIsPentagon && ownerVertexNum == NUM_PENT_VERTS)) {
  ------------------
  |  |   85|     59|#define NUM_PENT_VERTS 5
  ------------------
  |  Branch (280:18): [True: 59, False: 847]
  |  Branch (280:37): [True: 9, False: 50]
  ------------------
  281|    178|                ownerVertexNum = 0;
  282|    178|            }
  283|  1.07k|        }
  284|  2.77k|    }
  285|       |
  286|       |    // Create the vertex index
  287|  3.12k|    H3Index vertex = owner;
  288|  3.12k|    H3_SET_MODE(vertex, H3_VERTEX_MODE);
  ------------------
  |  |  113|  3.12k|    (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   59|  3.12k|#define H3_MODE_MASK_NEGATIVE (~H3_MODE_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   56|  3.12k|#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   35|  3.12k|#define H3_MODE_OFFSET 59
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   35|  3.12k|#define H3_MODE_OFFSET 59
  |  |  ------------------
  ------------------
  289|  3.12k|    H3_SET_RESERVED_BITS(vertex, ownerVertexNum);
  ------------------
  |  |  149|  3.12k|    (h3) = (((h3)&H3_RESERVED_MASK_NEGATIVE) | \
  |  |  ------------------
  |  |  |  |   77|  3.12k|#define H3_RESERVED_MASK_NEGATIVE (~H3_RESERVED_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   74|  3.12k|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   44|  3.12k|#define H3_RESERVED_OFFSET 56
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  150|  3.12k|            (((uint64_t)(v)) << H3_RESERVED_OFFSET))
  |  |  ------------------
  |  |  |  |   44|  3.12k|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  290|  3.12k|    *out = vertex;
  291|       |
  292|  3.12k|    return E_SUCCESS;
  293|  3.25k|}
cellToVertexes:
  300|    589|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|    589|    bool isPent = H3_EXPORT(isPentagon)(cell);
  ------------------
  |  |   36|    589|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    589|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    589|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  304|  3.48k|    for (int i = 0; i < NUM_HEX_VERTS; i++) {
  ------------------
  |  |   83|  3.48k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (304:21): [True: 3.00k, False: 475]
  ------------------
  305|  3.00k|        if (i == 5 && isPent) {
  ------------------
  |  Branch (305:13): [True: 475, False: 2.53k]
  |  Branch (305:23): [True: 29, False: 446]
  ------------------
  306|     29|            vertexes[i] = H3_NULL;
  ------------------
  |  |   76|     29|#define H3_NULL 0
  ------------------
  307|  2.98k|        } else {
  308|  2.98k|            H3Error cellError = H3_EXPORT(cellToVertex)(cell, i, &vertexes[i]);
  ------------------
  |  |   36|  2.98k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  2.98k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  2.98k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  309|  2.98k|            if (cellError) {
  ------------------
  |  Branch (309:17): [True: 114, False: 2.86k]
  ------------------
  310|    114|                return cellError;
  311|    114|            }
  312|  2.98k|        }
  313|  3.00k|    }
  314|    475|    return E_SUCCESS;
  315|    589|}
vertexToLatLng:
  322|    589|H3Error H3_EXPORT(vertexToLatLng)(H3Index vertex, LatLng *coord) {
  323|       |    // Get the vertex number and owner from the vertex
  324|    589|    int vertexNum = H3_GET_RESERVED_BITS(vertex);
  ------------------
  |  |  156|    589|    ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET)))
  |  |  ------------------
  |  |  |  |   74|    589|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|    589|#define H3_RESERVED_OFFSET 56
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET)))
  |  |  ------------------
  |  |  |  |   44|    589|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  325|    589|    H3Index owner = vertex;
  326|    589|    H3_SET_MODE(owner, H3_CELL_MODE);
  ------------------
  |  |  113|    589|    (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   59|    589|#define H3_MODE_MASK_NEGATIVE (~H3_MODE_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   56|    589|#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   35|    589|#define H3_MODE_OFFSET 59
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   35|    589|#define H3_MODE_OFFSET 59
  |  |  ------------------
  ------------------
  327|    589|    H3_SET_RESERVED_BITS(owner, 0);
  ------------------
  |  |  149|    589|    (h3) = (((h3)&H3_RESERVED_MASK_NEGATIVE) | \
  |  |  ------------------
  |  |  |  |   77|    589|#define H3_RESERVED_MASK_NEGATIVE (~H3_RESERVED_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   74|    589|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   44|    589|#define H3_RESERVED_OFFSET 56
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  150|    589|            (((uint64_t)(v)) << H3_RESERVED_OFFSET))
  |  |  ------------------
  |  |  |  |   44|    589|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  328|       |
  329|       |    // Get the single vertex from the boundary
  330|    589|    CellBoundary gb;
  331|    589|    FaceIJK fijk;
  332|    589|    H3Error fijkError = _h3ToFaceIjk(owner, &fijk);
  333|    589|    if (fijkError) {
  ------------------
  |  Branch (333:9): [True: 7, False: 582]
  ------------------
  334|      7|        return fijkError;
  335|      7|    }
  336|    582|    int res = H3_GET_RESOLUTION(owner);
  ------------------
  |  |  129|    582|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|    582|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|    582|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|    582|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  337|       |
  338|    582|    if (H3_EXPORT(isPentagon)(owner)) {
  ------------------
  |  |   36|    582|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    582|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    582|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (338:9): [True: 29, False: 553]
  ------------------
  339|     29|        _faceIjkPentToCellBoundary(&fijk, res, vertexNum, 1, &gb);
  340|    553|    } else {
  341|    553|        _faceIjkToCellBoundary(&fijk, res, vertexNum, 1, &gb);
  342|    553|    }
  343|       |
  344|       |    // Copy from boundary to output coord
  345|    582|    *coord = gb.verts[0];
  346|    582|    return E_SUCCESS;
  347|    589|}
isValidVertex:
  354|    589|int H3_EXPORT(isValidVertex)(H3Index vertex) {
  355|    589|    if (H3_GET_MODE(vertex) != H3_VERTEX_MODE) {
  ------------------
  |  |  107|    589|#define H3_GET_MODE(h3) ((int)((((h3)&H3_MODE_MASK) >> H3_MODE_OFFSET)))
  |  |  ------------------
  |  |  |  |   56|    589|#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   35|    589|#define H3_MODE_OFFSET 59
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_MODE(h3) ((int)((((h3)&H3_MODE_MASK) >> H3_MODE_OFFSET)))
  |  |  ------------------
  |  |  |  |   35|    589|#define H3_MODE_OFFSET 59
  |  |  ------------------
  ------------------
                  if (H3_GET_MODE(vertex) != H3_VERTEX_MODE) {
  ------------------
  |  |   93|    589|#define H3_VERTEX_MODE 4
  ------------------
  |  Branch (355:9): [True: 349, False: 240]
  ------------------
  356|    349|        return 0;
  357|    349|    }
  358|       |
  359|    240|    int vertexNum = H3_GET_RESERVED_BITS(vertex);
  ------------------
  |  |  156|    240|    ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET)))
  |  |  ------------------
  |  |  |  |   74|    240|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|    240|#define H3_RESERVED_OFFSET 56
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET)))
  |  |  ------------------
  |  |  |  |   44|    240|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  360|    240|    H3Index owner = vertex;
  361|    240|    H3_SET_MODE(owner, H3_CELL_MODE);
  ------------------
  |  |  113|    240|    (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   59|    240|#define H3_MODE_MASK_NEGATIVE (~H3_MODE_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   56|    240|#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   35|    240|#define H3_MODE_OFFSET 59
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   35|    240|#define H3_MODE_OFFSET 59
  |  |  ------------------
  ------------------
  362|    240|    H3_SET_RESERVED_BITS(owner, 0);
  ------------------
  |  |  149|    240|    (h3) = (((h3)&H3_RESERVED_MASK_NEGATIVE) | \
  |  |  ------------------
  |  |  |  |   77|    240|#define H3_RESERVED_MASK_NEGATIVE (~H3_RESERVED_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   74|    240|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   44|    240|#define H3_RESERVED_OFFSET 56
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  150|    240|            (((uint64_t)(v)) << H3_RESERVED_OFFSET))
  |  |  ------------------
  |  |  |  |   44|    240|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  363|       |
  364|    240|    if (!H3_EXPORT(isValidCell)(owner)) {
  ------------------
  |  |   36|    240|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    240|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    240|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (364:9): [True: 103, False: 137]
  ------------------
  365|    103|        return 0;
  366|    103|    }
  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|    137|    H3Index canonical;
  371|    137|    if (H3_EXPORT(cellToVertex)(owner, vertexNum, &canonical)) {
  ------------------
  |  |   36|    137|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    137|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    137|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (371:9): [True: 7, False: 130]
  ------------------
  372|      7|        return 0;
  373|      7|    }
  374|       |
  375|    130|    return vertex == canonical ? 1 : 0;
  ------------------
  |  Branch (375:12): [True: 17, False: 113]
  ------------------
  376|    137|}
vertex.c:vertexRotations:
   53|  7.46k|static H3Error vertexRotations(H3Index cell, int *out) {
   54|       |    // Get the face and other info for the origin
   55|  7.46k|    FaceIJK fijk;
   56|  7.46k|    H3Error err = _h3ToFaceIjk(cell, &fijk);
   57|  7.46k|    if (err) {
  ------------------
  |  Branch (57:9): [True: 6, False: 7.45k]
  ------------------
   58|      6|        return err;
   59|      6|    }
   60|  7.45k|    int baseCell = H3_EXPORT(getBaseCellNumber)(cell);
  ------------------
  |  |   36|  7.45k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  7.45k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  7.45k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   61|  7.45k|    int cellLeadingDigit = _h3LeadingNonZeroDigit(cell);
   62|       |
   63|       |    // get the base cell face
   64|  7.45k|    FaceIJK baseFijk;
   65|  7.45k|    _baseCellToFaceIjk(baseCell, &baseFijk);
   66|       |
   67|  7.45k|    int ccwRot60 = _baseCellToCCWrot60(baseCell, fijk.face);
   68|       |
   69|  7.45k|    if (_isBaseCellPentagon(baseCell)) {
  ------------------
  |  Branch (69:9): [True: 3.33k, False: 4.12k]
  ------------------
   70|       |        // Find the appropriate direction-to-face mapping
   71|  3.33k|        PentagonDirectionFaces dirFaces;
   72|       |        // We never hit the end condition
   73|  3.33k|        int p = 0;
   74|       |        // Don't use a for loop here, for coverage reasons.
   75|  19.0k|        while (ALWAYS(p < NUM_PENTAGONS)) {
  ------------------
  |  |  118|  19.0k|#define ALWAYS(X) ((X) ? 1 : (assert(0), 0))
  |  |  ------------------
  |  |  |  Branch (118:19): [True: 19.0k, False: 0]
  |  |  |  Branch (118:20): [True: 19.0k, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (75:16): [Folded, False: 0]
  |  Branch (75:16): [Folded, False: 0]
  ------------------
   76|  19.0k|            if (pentagonDirectionFaces[p].baseCell == baseCell) {
  ------------------
  |  Branch (76:17): [True: 3.33k, False: 15.7k]
  ------------------
   77|  3.33k|                dirFaces = pentagonDirectionFaces[p];
   78|  3.33k|                break;
   79|  3.33k|            }
   80|  15.7k|            p++;
   81|  15.7k|        }
   82|  3.33k|        if (NEVER(p == NUM_PENTAGONS)) {
  ------------------
  |  |  119|  3.33k|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 3.33k]
  |  |  |  Branch (119:19): [True: 0, False: 3.33k]
  |  |  ------------------
  ------------------
  |  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|  3.33k|        if (fijk.face != baseFijk.face &&
  ------------------
  |  Branch (87:13): [True: 2.64k, False: 691]
  ------------------
   88|  2.64k|            (_isBaseCellPolarPentagon(baseCell) ||
  ------------------
  |  Branch (88:14): [True: 796, False: 1.85k]
  ------------------
   89|  1.85k|             fijk.face ==
  ------------------
  |  Branch (89:14): [True: 435, False: 1.41k]
  ------------------
   90|  1.85k|                 dirFaces.faces[IK_AXES_DIGIT - DIRECTION_INDEX_OFFSET])) {
  ------------------
  |  |   32|  1.85k|#define DIRECTION_INDEX_OFFSET 2
  ------------------
   91|  1.23k|            ccwRot60 = (ccwRot60 + 1) % 6;
   92|  1.23k|        }
   93|       |
   94|       |        // Check whether the cell crosses a deleted pentagon subsequence
   95|  3.33k|        if (cellLeadingDigit == JK_AXES_DIGIT &&
  ------------------
  |  Branch (95:13): [True: 569, False: 2.76k]
  ------------------
   96|    569|            fijk.face ==
  ------------------
  |  Branch (96:13): [True: 163, False: 406]
  ------------------
   97|    569|                dirFaces.faces[IK_AXES_DIGIT - DIRECTION_INDEX_OFFSET]) {
  ------------------
  |  |   32|    569|#define DIRECTION_INDEX_OFFSET 2
  ------------------
   98|       |            // Crosses from JK to IK: Rotate CW
   99|    163|            ccwRot60 = (ccwRot60 + 5) % 6;
  100|  3.17k|        } else if (cellLeadingDigit == IK_AXES_DIGIT &&
  ------------------
  |  Branch (100:20): [True: 607, False: 2.56k]
  ------------------
  101|    607|                   fijk.face ==
  ------------------
  |  Branch (101:20): [True: 81, False: 526]
  ------------------
  102|    607|                       dirFaces.faces[JK_AXES_DIGIT - DIRECTION_INDEX_OFFSET]) {
  ------------------
  |  |   32|    607|#define DIRECTION_INDEX_OFFSET 2
  ------------------
  103|       |            // Crosses from IK to JK: Rotate CCW
  104|     81|            ccwRot60 = (ccwRot60 + 1) % 6;
  105|     81|        }
  106|  3.33k|    }
  107|  7.45k|    *out = ccwRot60;
  108|  7.45k|    return E_SUCCESS;
  109|  7.45k|}

