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

faceijk.c:_ijkToHex2d:
  244|    556|static inline void _ijkToHex2d(const CoordIJK *h, Vec2d *v) {
  245|    556|    int i = h->i - h->k;
  246|    556|    int j = h->j - h->k;
  247|       |
  248|    556|    v->x = i - 0.5 * j;
  249|    556|    v->y = j * M_SQRT3_2;
  ------------------
  |  |   44|    556|#define M_SQRT3_2 0.8660254037844386467637231707529361834714
  ------------------
  250|    556|}
faceijk.c:_ijkRotate60ccw:
  614|  18.5k|static inline void _ijkRotate60ccw(CoordIJK *ijk) {
  615|       |    // unit vector rotations
  616|  18.5k|    CoordIJK iVec = {1, 1, 0};
  617|  18.5k|    CoordIJK jVec = {0, 1, 1};
  618|  18.5k|    CoordIJK kVec = {1, 0, 1};
  619|       |
  620|  18.5k|    _ijkScale(&iVec, ijk->i);
  621|  18.5k|    _ijkScale(&jVec, ijk->j);
  622|  18.5k|    _ijkScale(&kVec, ijk->k);
  623|       |
  624|  18.5k|    _ijkAdd(&iVec, &jVec, ijk);
  625|  18.5k|    _ijkAdd(ijk, &kVec, ijk);
  626|       |
  627|  18.5k|    _ijkNormalize(ijk);
  628|  18.5k|}
faceijk.c:_ijkScale:
  155|  67.4k|static inline void _ijkScale(CoordIJK *c, int factor) {
  156|  67.4k|    c->i *= factor;
  157|  67.4k|    c->j *= factor;
  158|  67.4k|    c->k *= factor;
  159|  67.4k|}
faceijk.c:_ijkAdd:
  129|  50.7k|                           CoordIJK *sum) {
  130|  50.7k|    sum->i = h1->i + h2->i;
  131|  50.7k|    sum->j = h1->j + h2->j;
  132|  50.7k|    sum->k = h1->k + h2->k;
  133|  50.7k|}
faceijk.c:_ijkNormalize:
  207|  29.7k|static inline void _ijkNormalize(CoordIJK *c) {
  208|       |    // remove any negative values
  209|  29.7k|    if (c->i < 0) {
  ------------------
  |  Branch (209:9): [True: 0, False: 29.7k]
  ------------------
  210|      0|        c->j -= c->i;
  211|      0|        c->k -= c->i;
  212|      0|        c->i = 0;
  213|      0|    }
  214|       |
  215|  29.7k|    if (c->j < 0) {
  ------------------
  |  Branch (215:9): [True: 0, False: 29.7k]
  ------------------
  216|      0|        c->i -= c->j;
  217|      0|        c->k -= c->j;
  218|      0|        c->j = 0;
  219|      0|    }
  220|       |
  221|  29.7k|    if (c->k < 0) {
  ------------------
  |  Branch (221:9): [True: 0, False: 29.7k]
  ------------------
  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|  29.7k|    int min = c->i;
  229|  29.7k|    if (c->j < min) min = c->j;
  ------------------
  |  Branch (229:9): [True: 13.0k, False: 16.7k]
  ------------------
  230|  29.7k|    if (c->k < min) min = c->k;
  ------------------
  |  Branch (230:9): [True: 10.8k, False: 18.8k]
  ------------------
  231|  29.7k|    if (min > 0) {
  ------------------
  |  Branch (231:9): [True: 28.2k, False: 1.51k]
  ------------------
  232|  28.2k|        c->i -= min;
  233|  28.2k|        c->j -= min;
  234|  28.2k|        c->k -= min;
  235|  28.2k|    }
  236|  29.7k|}
faceijk.c:_downAp3:
  557|    556|static inline void _downAp3(CoordIJK *ijk) {
  558|       |    // res r unit vectors in res r+1
  559|    556|    CoordIJK iVec = {2, 0, 1};
  560|    556|    CoordIJK jVec = {1, 2, 0};
  561|    556|    CoordIJK kVec = {0, 1, 2};
  562|       |
  563|    556|    _ijkScale(&iVec, ijk->i);
  564|    556|    _ijkScale(&jVec, ijk->j);
  565|    556|    _ijkScale(&kVec, ijk->k);
  566|       |
  567|    556|    _ijkAdd(&iVec, &jVec, ijk);
  568|    556|    _ijkAdd(ijk, &kVec, ijk);
  569|       |
  570|    556|    _ijkNormalize(ijk);
  571|    556|}
faceijk.c:_downAp3r:
  579|    556|static inline void _downAp3r(CoordIJK *ijk) {
  580|       |    // res r unit vectors in res r+1
  581|    556|    CoordIJK iVec = {2, 1, 0};
  582|    556|    CoordIJK jVec = {0, 2, 1};
  583|    556|    CoordIJK kVec = {1, 0, 2};
  584|       |
  585|    556|    _ijkScale(&iVec, ijk->i);
  586|    556|    _ijkScale(&jVec, ijk->j);
  587|    556|    _ijkScale(&kVec, ijk->k);
  588|       |
  589|    556|    _ijkAdd(&iVec, &jVec, ijk);
  590|    556|    _ijkAdd(ijk, &kVec, ijk);
  591|       |
  592|    556|    _ijkNormalize(ijk);
  593|    556|}
faceijk.c:_downAp7r:
  534|    415|static inline void _downAp7r(CoordIJK *ijk) {
  535|       |    // res r unit vectors in res r+1
  536|    415|    CoordIJK iVec = {3, 1, 0};
  537|    415|    CoordIJK jVec = {0, 3, 1};
  538|    415|    CoordIJK kVec = {1, 0, 3};
  539|       |
  540|    415|    _ijkScale(&iVec, ijk->i);
  541|    415|    _ijkScale(&jVec, ijk->j);
  542|    415|    _ijkScale(&kVec, ijk->k);
  543|       |
  544|    415|    _ijkAdd(&iVec, &jVec, ijk);
  545|    415|    _ijkAdd(ijk, &kVec, ijk);
  546|       |
  547|    415|    _ijkNormalize(ijk);
  548|    415|}
faceijk.c:_setIJK:
  103|    457|static inline void _setIJK(CoordIJK *ijk, int i, int j, int k) {
  104|    457|    ijk->i = i;
  105|    457|    ijk->j = j;
  106|    457|    ijk->k = k;
  107|    457|}
faceijk.c:_ijkSub:
  143|    457|                           CoordIJK *diff) {
  144|    457|    diff->i = h1->i - h2->i;
  145|    457|    diff->j = h1->j - h2->j;
  146|    457|    diff->k = h1->k - h2->k;
  147|    457|}
faceijk.c:_ijkRotate60cw:
  635|    457|static inline void _ijkRotate60cw(CoordIJK *ijk) {
  636|       |    // unit vector rotations
  637|    457|    CoordIJK iVec = {1, 0, 1};
  638|    457|    CoordIJK jVec = {1, 1, 0};
  639|    457|    CoordIJK kVec = {0, 1, 1};
  640|       |
  641|    457|    _ijkScale(&iVec, ijk->i);
  642|    457|    _ijkScale(&jVec, ijk->j);
  643|    457|    _ijkScale(&kVec, ijk->k);
  644|       |
  645|    457|    _ijkAdd(&iVec, &jVec, ijk);
  646|    457|    _ijkAdd(ijk, &kVec, ijk);
  647|       |
  648|    457|    _ijkNormalize(ijk);
  649|    457|}
h3Index.c:_rotate60ccw:
  656|  12.6k|static inline Direction _rotate60ccw(Direction digit) {
  657|  12.6k|    switch (digit) {
  658|  2.46k|        case K_AXES_DIGIT:
  ------------------
  |  Branch (658:9): [True: 2.46k, False: 10.1k]
  ------------------
  659|  2.46k|            return IK_AXES_DIGIT;
  660|  2.16k|        case IK_AXES_DIGIT:
  ------------------
  |  Branch (660:9): [True: 2.16k, False: 10.4k]
  ------------------
  661|  2.16k|            return I_AXES_DIGIT;
  662|  1.85k|        case I_AXES_DIGIT:
  ------------------
  |  Branch (662:9): [True: 1.85k, False: 10.7k]
  ------------------
  663|  1.85k|            return IJ_AXES_DIGIT;
  664|  1.69k|        case IJ_AXES_DIGIT:
  ------------------
  |  Branch (664:9): [True: 1.69k, False: 10.9k]
  ------------------
  665|  1.69k|            return J_AXES_DIGIT;
  666|  1.89k|        case J_AXES_DIGIT:
  ------------------
  |  Branch (666:9): [True: 1.89k, False: 10.7k]
  ------------------
  667|  1.89k|            return JK_AXES_DIGIT;
  668|  2.28k|        case JK_AXES_DIGIT:
  ------------------
  |  Branch (668:9): [True: 2.28k, False: 10.3k]
  ------------------
  669|  2.28k|            return K_AXES_DIGIT;
  670|    279|        default:
  ------------------
  |  Branch (670:9): [True: 279, False: 12.3k]
  ------------------
  671|    279|            return digit;
  672|  12.6k|    }
  673|  12.6k|}
h3Index.c:_rotate60cw:
  680|  12.1k|static inline Direction _rotate60cw(Direction digit) {
  681|  12.1k|    switch (digit) {
  682|  1.40k|        case K_AXES_DIGIT:
  ------------------
  |  Branch (682:9): [True: 1.40k, False: 10.7k]
  ------------------
  683|  1.40k|            return JK_AXES_DIGIT;
  684|  1.16k|        case JK_AXES_DIGIT:
  ------------------
  |  Branch (684:9): [True: 1.16k, False: 10.9k]
  ------------------
  685|  1.16k|            return J_AXES_DIGIT;
  686|    814|        case J_AXES_DIGIT:
  ------------------
  |  Branch (686:9): [True: 814, False: 11.3k]
  ------------------
  687|    814|            return IJ_AXES_DIGIT;
  688|  1.31k|        case IJ_AXES_DIGIT:
  ------------------
  |  Branch (688:9): [True: 1.31k, False: 10.8k]
  ------------------
  689|  1.31k|            return I_AXES_DIGIT;
  690|  1.38k|        case I_AXES_DIGIT:
  ------------------
  |  Branch (690:9): [True: 1.38k, False: 10.7k]
  ------------------
  691|  1.38k|            return IK_AXES_DIGIT;
  692|  2.49k|        case IK_AXES_DIGIT:
  ------------------
  |  Branch (692:9): [True: 2.49k, False: 9.65k]
  ------------------
  693|  2.49k|            return K_AXES_DIGIT;
  694|  3.57k|        default:
  ------------------
  |  Branch (694:9): [True: 3.57k, False: 8.58k]
  ------------------
  695|  3.57k|            return digit;
  696|  12.1k|    }
  697|  12.1k|}
h3Index.c:_downAp7:
  512|  41.2k|static inline void _downAp7(CoordIJK *ijk) {
  513|       |    // res r unit vectors in res r+1
  514|  41.2k|    CoordIJK iVec = {3, 0, 1};
  515|  41.2k|    CoordIJK jVec = {1, 3, 0};
  516|  41.2k|    CoordIJK kVec = {0, 1, 3};
  517|       |
  518|  41.2k|    _ijkScale(&iVec, ijk->i);
  519|  41.2k|    _ijkScale(&jVec, ijk->j);
  520|  41.2k|    _ijkScale(&kVec, ijk->k);
  521|       |
  522|  41.2k|    _ijkAdd(&iVec, &jVec, ijk);
  523|  41.2k|    _ijkAdd(ijk, &kVec, ijk);
  524|       |
  525|  41.2k|    _ijkNormalize(ijk);
  526|  41.2k|}
h3Index.c:_ijkScale:
  155|   247k|static inline void _ijkScale(CoordIJK *c, int factor) {
  156|   247k|    c->i *= factor;
  157|   247k|    c->j *= factor;
  158|   247k|    c->k *= factor;
  159|   247k|}
h3Index.c:_ijkAdd:
  129|   221k|                           CoordIJK *sum) {
  130|   221k|    sum->i = h1->i + h2->i;
  131|   221k|    sum->j = h1->j + h2->j;
  132|   221k|    sum->k = h1->k + h2->k;
  133|   221k|}
h3Index.c:_upAp7r:
  494|  3.05k|static inline void _upAp7r(CoordIJK *ijk) {
  495|       |    // convert to CoordIJ
  496|  3.05k|    int i = ijk->i - ijk->k;
  497|  3.05k|    int j = ijk->j - ijk->k;
  498|       |
  499|  3.05k|    ijk->i = (int)lround((2 * i + j) * M_ONESEVENTH);
  ------------------
  |  |   54|  3.05k|#define M_ONESEVENTH 0.14285714285714285714285714285714285
  ------------------
  500|  3.05k|    ijk->j = (int)lround((3 * j - i) * M_ONESEVENTH);
  ------------------
  |  |   54|  3.05k|#define M_ONESEVENTH 0.14285714285714285714285714285714285
  ------------------
  501|  3.05k|    ijk->k = 0;
  502|  3.05k|    _ijkNormalize(ijk);
  503|  3.05k|}
h3Index.c:_downAp7r:
  534|  41.1k|static inline void _downAp7r(CoordIJK *ijk) {
  535|       |    // res r unit vectors in res r+1
  536|  41.1k|    CoordIJK iVec = {3, 1, 0};
  537|  41.1k|    CoordIJK jVec = {0, 3, 1};
  538|  41.1k|    CoordIJK kVec = {1, 0, 3};
  539|       |
  540|  41.1k|    _ijkScale(&iVec, ijk->i);
  541|  41.1k|    _ijkScale(&jVec, ijk->j);
  542|  41.1k|    _ijkScale(&kVec, ijk->k);
  543|       |
  544|  41.1k|    _ijkAdd(&iVec, &jVec, ijk);
  545|  41.1k|    _ijkAdd(ijk, &kVec, ijk);
  546|       |
  547|  41.1k|    _ijkNormalize(ijk);
  548|  41.1k|}
h3Index.c:_ijkNormalize:
  207|   142k|static inline void _ijkNormalize(CoordIJK *c) {
  208|       |    // remove any negative values
  209|   142k|    if (c->i < 0) {
  ------------------
  |  Branch (209:9): [True: 1.10k, False: 141k]
  ------------------
  210|  1.10k|        c->j -= c->i;
  211|  1.10k|        c->k -= c->i;
  212|  1.10k|        c->i = 0;
  213|  1.10k|    }
  214|       |
  215|   142k|    if (c->j < 0) {
  ------------------
  |  Branch (215:9): [True: 894, False: 141k]
  ------------------
  216|    894|        c->i -= c->j;
  217|    894|        c->k -= c->j;
  218|    894|        c->j = 0;
  219|    894|    }
  220|       |
  221|   142k|    if (c->k < 0) {
  ------------------
  |  Branch (221:9): [True: 0, False: 142k]
  ------------------
  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|   142k|    int min = c->i;
  229|   142k|    if (c->j < min) min = c->j;
  ------------------
  |  Branch (229:9): [True: 98.4k, False: 43.8k]
  ------------------
  230|   142k|    if (c->k < min) min = c->k;
  ------------------
  |  Branch (230:9): [True: 37.4k, False: 104k]
  ------------------
  231|   142k|    if (min > 0) {
  ------------------
  |  Branch (231:9): [True: 93.0k, False: 49.1k]
  ------------------
  232|  93.0k|        c->i -= min;
  233|  93.0k|        c->j -= min;
  234|  93.0k|        c->k -= min;
  235|  93.0k|    }
  236|   142k|}
h3Index.c:_neighbor:
  602|  76.8k|static inline void _neighbor(CoordIJK *ijk, Direction digit) {
  603|  76.8k|    if (digit > CENTER_DIGIT && digit < NUM_DIGITS) {
  ------------------
  |  Branch (603:9): [True: 60.3k, False: 16.5k]
  |  Branch (603:33): [True: 56.6k, False: 3.62k]
  ------------------
  604|  56.6k|        _ijkAdd(ijk, &UNIT_VECS[digit], ijk);
  605|  56.6k|        _ijkNormalize(ijk);
  606|  56.6k|    }
  607|  76.8k|}

faceijk.c:vec3LinComb:
   62|  1.66k|static inline Vec3d vec3LinComb(double a, Vec3d v1, double b, Vec3d v2) {
   63|  1.66k|    Vec3d out = {
   64|  1.66k|        .x = a * v1.x + b * v2.x,
   65|  1.66k|        .y = a * v1.y + b * v2.y,
   66|  1.66k|        .z = a * v1.z + b * v2.z,
   67|  1.66k|    };
   68|  1.66k|    return out;
   69|  1.66k|}
faceijk.c:vec3NormSq:
   84|  1.11k|static inline double vec3NormSq(Vec3d v) { return vec3Dot(v, v); }
faceijk.c:vec3Dot:
   80|  1.66k|static inline double vec3Dot(Vec3d v1, Vec3d v2) {
   81|  1.66k|    return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
   82|  1.66k|}
faceijk.c:vec3Cross:
   71|    556|static inline Vec3d vec3Cross(Vec3d v1, Vec3d v2) {
   72|    556|    Vec3d out = {
   73|    556|        .x = v1.y * v2.z - v1.z * v2.y,
   74|    556|        .y = v1.z * v2.x - v1.x * v2.z,
   75|    556|        .z = v1.x * v2.y - v1.y * v2.x,
   76|    556|    };
   77|    556|    return out;
   78|    556|}
faceijk.c:vec3Normalize:
   88|  1.11k|static inline void vec3Normalize(Vec3d *v) {
   89|  1.11k|    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.11k|    double s = 0.0;
   96|  1.11k|    if (norm > 0.0) {
  ------------------
  |  Branch (96:9): [True: 1.11k, False: 0]
  ------------------
   97|  1.11k|        s = 1.0 / norm;
   98|  1.11k|    }
   99|       |
  100|  1.11k|    v->x *= s;
  101|  1.11k|    v->y *= s;
  102|  1.11k|    v->z *= s;
  103|  1.11k|}
faceijk.c:vec3Norm:
   86|  1.11k|static inline double vec3Norm(Vec3d v) { return sqrt(vec3NormSq(v)); }
faceijk.c:vec3ToLatLng:
   54|    556|static inline LatLng vec3ToLatLng(Vec3d v) {
   55|    556|    LatLng out = {
   56|    556|        .lat = asin(v.z),
   57|    556|        .lng = atan2(v.y, v.x),
   58|    556|    };
   59|    556|    return out;
   60|    556|}

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

_isBaseCellPentagon:
  824|  52.3k|int _isBaseCellPentagon(int baseCell) {
  825|  52.3k|    if (baseCell < 0 || baseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |   81|  52.3k|#define NUM_BASE_CELLS 122
  ------------------
  |  Branch (825:9): [True: 0, False: 52.3k]
  |  Branch (825:25): [True: 34, False: 52.3k]
  ------------------
  826|       |        // Base cells less than zero can not be represented in an index
  827|     34|        return false;
  828|     34|    }
  829|  52.3k|    return baseCellData[baseCell].isPentagon;
  830|  52.3k|}
_isBaseCellPolarPentagon:
  834|  2.95k|bool _isBaseCellPolarPentagon(int baseCell) {
  835|  2.95k|    return baseCell == 4 || baseCell == 117;
  ------------------
  |  Branch (835:12): [True: 543, False: 2.41k]
  |  Branch (835:29): [True: 378, False: 2.03k]
  ------------------
  836|  2.95k|}
_baseCellToFaceIjk:
  866|  7.08k|void _baseCellToFaceIjk(int baseCell, FaceIJK *h) {
  867|  7.08k|    *h = baseCellData[baseCell].homeFijk;
  868|  7.08k|}
_baseCellToCCWrot60:
  877|  7.08k|int _baseCellToCCWrot60(int baseCell, int face) {
  878|  7.08k|    if (face < 0 || face >= NUM_ICOSA_FACES) return INVALID_ROTATIONS;
  ------------------
  |  |   79|  7.08k|#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.08k]
  |  Branch (878:21): [True: 0, False: 7.08k]
  ------------------
  879|  11.6k|    for (int i = 0; i < 3; i++) {
  ------------------
  |  Branch (879:21): [True: 11.6k, False: 0]
  ------------------
  880|  29.2k|        for (int j = 0; j < 3; j++) {
  ------------------
  |  Branch (880:25): [True: 24.7k, False: 4.55k]
  ------------------
  881|  80.5k|            for (int k = 0; k < 3; k++) {
  ------------------
  |  Branch (881:29): [True: 62.8k, False: 17.6k]
  ------------------
  882|  62.8k|                if (faceIjkBaseCells[face][i][j][k].baseCell == baseCell) {
  ------------------
  |  Branch (882:21): [True: 7.08k, False: 55.8k]
  ------------------
  883|  7.08k|                    return faceIjkBaseCells[face][i][j][k].ccwRot60;
  884|  7.08k|                }
  885|  62.8k|            }
  886|  24.7k|        }
  887|  11.6k|    }
  888|      0|    return INVALID_ROTATIONS;
  ------------------
  |  |   49|      0|#define INVALID_ROTATIONS -1
  ------------------
  889|  7.08k|}
_baseCellIsCwOffset:
  893|    113|bool _baseCellIsCwOffset(int baseCell, int testFace) {
  894|    113|    return baseCellData[baseCell].cwOffsetPent[0] == testFace ||
  ------------------
  |  Branch (894:12): [True: 38, False: 75]
  ------------------
  895|     75|           baseCellData[baseCell].cwOffsetPent[1] == testFace;
  ------------------
  |  Branch (895:12): [True: 75, False: 0]
  ------------------
  896|    113|}

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

getBaseCellNumber:
   98|  7.08k|int H3_EXPORT(getBaseCellNumber)(H3Index h) { return H3_GET_BASE_CELL(h); }
  ------------------
  |  |  118|  7.08k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  7.08k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  7.08k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  7.08k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
isValidCell:
  343|    241|int H3_EXPORT(isValidCell)(H3Index h) {
  344|       |    /*
  345|       |    Look for bit patterns that would disqualify an H3Index from
  346|       |    being valid. If identified, exit early.
  347|       |
  348|       |    For reference the H3 index bit layout:
  349|       |
  350|       |    |   Region   | # bits |
  351|       |    |------------|--------|
  352|       |    | High       |      1 |
  353|       |    | Mode       |      4 |
  354|       |    | Reserved   |      3 |
  355|       |    | Resolution |      4 |
  356|       |    | Base Cell  |      7 |
  357|       |    | Digit 1    |      3 |
  358|       |    | Digit 2    |      3 |
  359|       |    | ...        |    ... |
  360|       |    | Digit 15   |      3 |
  361|       |
  362|       |    Speed benefits come from using bit manipulation instead of loops,
  363|       |    whenever possible.
  364|       |    */
  365|    241|    if (!_hasGoodTopBits(h)) return false;
  ------------------
  |  Branch (365:9): [True: 6, False: 235]
  ------------------
  366|       |
  367|       |    // No need to check resolution; any 4 bits give a valid resolution.
  368|    235|    const int res = H3_GET_RESOLUTION(h);
  ------------------
  |  |  129|    235|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|    235|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|    235|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|    235|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  369|       |
  370|       |    // Get base cell number and check that it is valid.
  371|    235|    const int bc = H3_GET_BASE_CELL(h);
  ------------------
  |  |  118|    235|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|    235|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|    235|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|    235|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  372|    235|    if (bc >= NUM_BASE_CELLS) return false;
  ------------------
  |  |   81|    235|#define NUM_BASE_CELLS 122
  ------------------
  |  Branch (372:9): [True: 2, False: 233]
  ------------------
  373|       |
  374|    233|    if (_hasAny7UptoRes(h, res)) return false;
  ------------------
  |  Branch (374:9): [True: 33, False: 200]
  ------------------
  375|    200|    if (!_hasAll7AfterRes(h, res)) return false;
  ------------------
  |  Branch (375:9): [True: 62, False: 138]
  ------------------
  376|    138|    if (_hasDeletedSubsequence(h, bc)) return false;
  ------------------
  |  Branch (376:9): [True: 4, False: 134]
  ------------------
  377|       |
  378|       |    // If no disqualifications were identified, the index is a valid H3 cell.
  379|    134|    return true;
  380|    138|}
isPentagon:
  841|  13.9k|int H3_EXPORT(isPentagon)(H3Index h) {
  842|  13.9k|    return _isBaseCellPentagon(H3_GET_BASE_CELL(h)) &&
  ------------------
  |  |  118|  13.9k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  13.9k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  13.9k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  13.9k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  |  Branch (842:12): [True: 6.32k, False: 7.63k]
  ------------------
  843|  6.32k|           !_h3LeadingNonZeroDigit(h);
  ------------------
  |  Branch (843:12): [True: 617, False: 5.70k]
  ------------------
  844|  13.9k|}
_h3LeadingNonZeroDigit:
  851|  29.4k|Direction _h3LeadingNonZeroDigit(H3Index h) {
  852|  94.1k|    for (int r = 1; r <= H3_GET_RESOLUTION(h); r++)
  ------------------
  |  |  129|  94.1k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  94.1k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  94.1k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  94.1k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (852:21): [True: 91.2k, False: 2.93k]
  ------------------
  853|  91.2k|        if (H3_GET_INDEX_DIGIT(h, r)) return H3_GET_INDEX_DIGIT(h, r);
  ------------------
  |  |  141|  91.2k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  91.2k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  91.2k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  |  Branch (141:5): [True: 26.4k, False: 64.7k]
  |  |  ------------------
  |  |  142|  91.2k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  91.2k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
                      if (H3_GET_INDEX_DIGIT(h, r)) return H3_GET_INDEX_DIGIT(h, r);
  ------------------
  |  |  141|  26.4k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  26.4k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  26.4k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  26.4k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  26.4k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  854|       |
  855|       |    // if we're here it's all 0's
  856|  2.93k|    return CENTER_DIGIT;
  857|  29.4k|}
_h3RotatePent60ccw:
  863|    669|H3Index _h3RotatePent60ccw(H3Index h) {
  864|       |    // rotate in place; skips any leading 1 digits (k-axis)
  865|       |
  866|    669|    int foundFirstNonZeroDigit = 0;
  867|  5.77k|    for (int r = 1, res = H3_GET_RESOLUTION(h); r <= res; r++) {
  ------------------
  |  |  129|    669|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|    669|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|    669|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|    669|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (867:49): [True: 5.11k, False: 669]
  ------------------
  868|       |        // rotate this digit
  869|  5.11k|        H3_SET_INDEX_DIGIT(h, r, _rotate60ccw(H3_GET_INDEX_DIGIT(h, r)));
  ------------------
  |  |  162|  5.11k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  5.11k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  5.11k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  5.11k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  5.11k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  5.11k|            (((uint64_t)(digit))                                            \
  |  |  165|  5.11k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  5.11k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  5.11k|#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|  5.11k|        if (!foundFirstNonZeroDigit && H3_GET_INDEX_DIGIT(h, r) != 0) {
  ------------------
  |  |  141|    580|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|    580|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|    580|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|    580|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|    580|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  |  Branch (874:13): [True: 580, False: 4.53k]
  |  Branch (874:40): [True: 580, False: 0]
  ------------------
  875|    580|            foundFirstNonZeroDigit = 1;
  876|       |
  877|       |            // adjust for deleted k-axes sequence
  878|    580|            if (_h3LeadingNonZeroDigit(h) == K_AXES_DIGIT)
  ------------------
  |  Branch (878:17): [True: 228, False: 352]
  ------------------
  879|    228|                h = _h3Rotate60ccw(h);
  880|    580|        }
  881|  5.11k|    }
  882|    669|    return h;
  883|    669|}
_h3Rotate60ccw:
  914|  1.96k|H3Index _h3Rotate60ccw(H3Index h) {
  915|  9.49k|    for (int r = 1, res = H3_GET_RESOLUTION(h); r <= res; r++) {
  ------------------
  |  |  129|  1.96k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  1.96k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  1.96k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  1.96k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (915:49): [True: 7.52k, False: 1.96k]
  ------------------
  916|  7.52k|        Direction oldDigit = H3_GET_INDEX_DIGIT(h, r);
  ------------------
  |  |  141|  7.52k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  7.52k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  7.52k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  7.52k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  7.52k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  917|  7.52k|        H3_SET_INDEX_DIGIT(h, r, _rotate60ccw(oldDigit));
  ------------------
  |  |  162|  7.52k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  7.52k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  7.52k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  7.52k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  7.52k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  7.52k|            (((uint64_t)(digit))                                            \
  |  |  165|  7.52k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  7.52k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  7.52k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  ------------------
  918|  7.52k|    }
  919|       |
  920|  1.96k|    return h;
  921|  1.96k|}
_h3Rotate60cw:
  927|    958|H3Index _h3Rotate60cw(H3Index h) {
  928|  13.1k|    for (int r = 1, res = H3_GET_RESOLUTION(h); r <= res; r++) {
  ------------------
  |  |  129|    958|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|    958|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|    958|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|    958|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (928:49): [True: 12.1k, False: 958]
  ------------------
  929|  12.1k|        H3_SET_INDEX_DIGIT(h, r, _rotate60cw(H3_GET_INDEX_DIGIT(h, r)));
  ------------------
  |  |  162|  12.1k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  12.1k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  12.1k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  12.1k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  12.1k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  12.1k|            (((uint64_t)(digit))                                            \
  |  |  165|  12.1k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  12.1k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  12.1k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  ------------------
  930|  12.1k|    }
  931|       |
  932|    958|    return h;
  933|    958|}
_h3ToFaceIjkWithInitializedFijk:
 1086|  7.64k|int _h3ToFaceIjkWithInitializedFijk(H3Index h, FaceIJK *fijk) {
 1087|  7.64k|    CoordIJK *ijk = &fijk->coord;
 1088|  7.64k|    int res = H3_GET_RESOLUTION(h);
  ------------------
  |  |  129|  7.64k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  7.64k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  7.64k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  7.64k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
 1089|       |
 1090|       |    // center base cell hierarchy is entirely on this face
 1091|  7.64k|    int possibleOverage = 1;
 1092|  7.64k|    if (!_isBaseCellPentagon(H3_GET_BASE_CELL(h)) &&
  ------------------
  |  |  118|  7.64k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  7.64k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  7.64k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  7.64k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  |  Branch (1092:9): [True: 4.28k, False: 3.35k]
  ------------------
 1093|  4.28k|        (res == 0 ||
  ------------------
  |  Branch (1093:10): [True: 549, False: 3.73k]
  ------------------
 1094|  3.73k|         (fijk->coord.i == 0 && fijk->coord.j == 0 && fijk->coord.k == 0)))
  ------------------
  |  Branch (1094:11): [True: 2.18k, False: 1.55k]
  |  Branch (1094:33): [True: 790, False: 1.39k]
  |  Branch (1094:55): [True: 148, False: 642]
  ------------------
 1095|    697|        possibleOverage = 0;
 1096|       |
 1097|  84.4k|    for (int r = 1; r <= res; r++) {
  ------------------
  |  Branch (1097:21): [True: 76.8k, False: 7.64k]
  ------------------
 1098|  76.8k|        if (isResolutionClassIII(r)) {
  ------------------
  |  Branch (1098:13): [True: 41.2k, False: 35.5k]
  ------------------
 1099|       |            // Class III == rotate ccw
 1100|  41.2k|            _downAp7(ijk);
 1101|  41.2k|        } else {
 1102|       |            // Class II == rotate cw
 1103|  35.5k|            _downAp7r(ijk);
 1104|  35.5k|        }
 1105|       |
 1106|  76.8k|        _neighbor(ijk, H3_GET_INDEX_DIGIT(h, r));
  ------------------
  |  |  141|  76.8k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  76.8k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  76.8k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  76.8k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  76.8k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
 1107|  76.8k|    }
 1108|       |
 1109|  7.64k|    return possibleOverage;
 1110|  7.64k|}
_h3ToFaceIjk:
 1117|  7.65k|H3Error _h3ToFaceIjk(H3Index h, FaceIJK *fijk) {
 1118|  7.65k|    int baseCell = H3_GET_BASE_CELL(h);
  ------------------
  |  |  118|  7.65k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  7.65k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  7.65k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  7.65k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
 1119|  7.65k|    if (NEVER(baseCell < 0) || baseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |  119|  15.3k|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 7.65k]
  |  |  |  Branch (119:19): [True: 0, False: 7.65k]
  |  |  ------------------
  ------------------
                  if (NEVER(baseCell < 0) || baseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |   81|  7.65k|#define NUM_BASE_CELLS 122
  ------------------
  |  Branch (1119:9): [Folded, False: 0]
  |  Branch (1119:9): [Folded, False: 0]
  |  Branch (1119:32): [True: 15, False: 7.64k]
  ------------------
 1120|       |        // Base cells less than zero can not be represented in an index
 1121|       |        // To prevent reading uninitialized memory, we zero the output.
 1122|     15|        fijk->face = 0;
 1123|     15|        fijk->coord.i = fijk->coord.j = fijk->coord.k = 0;
 1124|     15|        return E_CELL_INVALID;
 1125|     15|    }
 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|  7.64k|    if (_isBaseCellPentagon(baseCell) && _h3LeadingNonZeroDigit(h) == 5)
  ------------------
  |  Branch (1128:9): [True: 3.35k, False: 4.28k]
  |  Branch (1128:42): [True: 762, False: 2.59k]
  ------------------
 1129|    762|        h = _h3Rotate60cw(h);
 1130|       |
 1131|       |    // start with the "home" face and ijk+ coordinates for the base cell of c
 1132|  7.64k|    *fijk = baseCellData[baseCell].homeFijk;
 1133|  7.64k|    if (!_h3ToFaceIjkWithInitializedFijk(h, fijk))
  ------------------
  |  Branch (1133:9): [True: 697, False: 6.94k]
  ------------------
 1134|    697|        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|  6.94k|    CoordIJK origIJK = fijk->coord;
 1140|       |
 1141|       |    // if we're in Class III, drop into the next finer Class II grid
 1142|  6.94k|    int res = H3_GET_RESOLUTION(h);
  ------------------
  |  |  129|  6.94k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  6.94k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  6.94k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  6.94k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
 1143|  6.94k|    if (isResolutionClassIII(res)) {
  ------------------
  |  Branch (1143:9): [True: 5.64k, False: 1.30k]
  ------------------
 1144|       |        // Class III
 1145|  5.64k|        _downAp7r(&fijk->coord);
 1146|  5.64k|        res++;
 1147|  5.64k|    }
 1148|       |
 1149|       |    // adjust for overage if needed
 1150|       |    // a pentagon base cell with a leading 4 digit requires special handling
 1151|  6.94k|    int pentLeading4 =
 1152|  6.94k|        (_isBaseCellPentagon(baseCell) && _h3LeadingNonZeroDigit(h) == 4);
  ------------------
  |  Branch (1152:10): [True: 3.35k, False: 3.58k]
  |  Branch (1152:43): [True: 895, False: 2.46k]
  ------------------
 1153|  6.94k|    if (_adjustOverageClassII(fijk, res, pentLeading4, 0) != NO_OVERAGE) {
  ------------------
  |  Branch (1153:9): [True: 3.67k, False: 3.26k]
  ------------------
 1154|       |        // if the base cell is a pentagon we have the potential for secondary
 1155|       |        // overages
 1156|  3.67k|        if (_isBaseCellPentagon(baseCell)) {
  ------------------
  |  Branch (1156:13): [True: 2.73k, False: 945]
  ------------------
 1157|  4.87k|            while (_adjustOverageClassII(fijk, res, 0, 0) != NO_OVERAGE)
  ------------------
  |  Branch (1157:20): [True: 2.14k, False: 2.73k]
  ------------------
 1158|  2.14k|                continue;
 1159|  2.73k|        }
 1160|       |
 1161|  3.67k|        if (res != H3_GET_RESOLUTION(h)) _upAp7r(&fijk->coord);
  ------------------
  |  |  129|  3.67k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  3.67k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  3.67k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  3.67k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (1161:13): [True: 3.05k, False: 619]
  ------------------
 1162|  3.67k|    } else if (res != H3_GET_RESOLUTION(h)) {
  ------------------
  |  |  129|  3.26k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  3.26k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  3.26k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  3.26k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (1162:16): [True: 2.58k, False: 681]
  ------------------
 1163|  2.58k|        fijk->coord = origIJK;
 1164|  2.58k|    }
 1165|  6.94k|    return E_SUCCESS;
 1166|  7.64k|}
isResolutionClassIII:
 1355|   100k|int isResolutionClassIII(int res) { return res % 2; }
h3Index.c:_hasGoodTopBits:
  216|    241|static inline bool _hasGoodTopBits(H3Index h) {
  217|    241|    h >>= (64 - 8);
  218|    241|    return h == 0b00001000;
  219|    241|}
h3Index.c:_hasAny7UptoRes:
  264|    233|static inline bool _hasAny7UptoRes(H3Index h, int res) {
  265|    233|    const uint64_t MHI = 0b100100100100100100100100100100100100100100100;
  266|    233|    const uint64_t MLO = MHI >> 2;
  267|       |
  268|    233|    int shift = 3 * (15 - res);
  269|    233|    h >>= shift;
  270|    233|    h <<= shift;
  271|    233|    h = (h & MHI & (~h - MLO));
  272|       |
  273|    233|    return h != 0;
  274|    233|}
h3Index.c:_hasAll7AfterRes:
  280|    200|static inline bool _hasAll7AfterRes(H3Index h, int res) {
  281|       |    // NOTE: res check is needed because we can't shift by 64
  282|    200|    if (res < 15) {
  ------------------
  |  Branch (282:9): [True: 97, False: 103]
  ------------------
  283|     97|        int shift = 19 + 3 * res;
  284|       |
  285|     97|        h = ~h;
  286|     97|        h <<= shift;
  287|     97|        h >>= shift;
  288|       |
  289|     97|        return h == 0;
  290|     97|    }
  291|    103|    return true;
  292|    200|}
h3Index.c:_hasDeletedSubsequence:
  327|    138|static inline bool _hasDeletedSubsequence(H3Index h, int base_cell) {
  328|    138|    if (isBaseCellPentagonArr[base_cell]) {
  ------------------
  |  Branch (328:9): [True: 79, False: 59]
  ------------------
  329|     79|        h <<= 19;
  330|     79|        h >>= 19;
  331|       |
  332|     79|        if (h == 0) return false;  // all zeros: res 15 pentagon
  ------------------
  |  Branch (332:13): [True: 2, False: 77]
  ------------------
  333|     77|        return _firstOneIndex(h) % 3 == 0;
  334|     79|    }
  335|     59|    return false;
  336|    138|}
h3Index.c:_firstOneIndex:
  300|     77|static inline int _firstOneIndex(H3Index h) {
  301|     77|#if defined(__GNUC__) || defined(__clang__)
  302|     77|    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|     77|}

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

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

vertexNumForDirection:
  130|  2.09k|int vertexNumForDirection(const H3Index origin, const Direction direction) {
  131|  2.09k|    int isPent = H3_EXPORT(isPentagon)(origin);
  ------------------
  |  |   36|  2.09k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  2.09k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  2.09k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  132|       |    // Check for invalid directions
  133|  2.09k|    if (direction == CENTER_DIGIT || direction >= INVALID_DIGIT ||
  ------------------
  |  Branch (133:9): [True: 0, False: 2.09k]
  |  Branch (133:38): [True: 21, False: 2.07k]
  ------------------
  134|  2.07k|        (isPent && direction == K_AXES_DIGIT))
  ------------------
  |  Branch (134:10): [True: 107, False: 1.97k]
  |  Branch (134:20): [True: 0, False: 107]
  ------------------
  135|     21|        return INVALID_VERTEX_NUM;
  ------------------
  |  |   36|     21|#define INVALID_VERTEX_NUM -1
  ------------------
  136|       |
  137|       |    // Determine the vertex rotations for this cell
  138|  2.07k|    int rotations;
  139|  2.07k|    H3Error err = vertexRotations(origin, &rotations);
  140|  2.07k|    if (err) {
  ------------------
  |  Branch (140:9): [True: 0, False: 2.07k]
  ------------------
  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.07k|    if (isPent) {
  ------------------
  |  Branch (145:9): [True: 107, False: 1.97k]
  ------------------
  146|    107|        return (directionToVertexNumPent[direction] + NUM_PENT_VERTS -
  ------------------
  |  |   85|    107|#define NUM_PENT_VERTS 5
  ------------------
  147|    107|                rotations) %
  148|    107|               NUM_PENT_VERTS;
  ------------------
  |  |   85|    107|#define NUM_PENT_VERTS 5
  ------------------
  149|  1.97k|    } else {
  150|  1.97k|        return (directionToVertexNumHex[direction] + NUM_HEX_VERTS -
  ------------------
  |  |   83|  1.97k|#define NUM_HEX_VERTS 6
  ------------------
  151|  1.97k|                rotations) %
  152|  1.97k|               NUM_HEX_VERTS;
  ------------------
  |  |   83|  1.97k|#define NUM_HEX_VERTS 6
  ------------------
  153|  1.97k|    }
  154|  2.07k|}
directionForVertexNum:
  173|  5.01k|Direction directionForVertexNum(const H3Index origin, const int vertexNum) {
  174|  5.01k|    int isPent = H3_EXPORT(isPentagon)(origin);
  ------------------
  |  |   36|  5.01k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  5.01k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  5.01k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  175|       |    // Check for invalid vertexes
  176|  5.01k|    if (vertexNum < 0 ||
  ------------------
  |  Branch (176:9): [True: 0, False: 5.01k]
  ------------------
  177|  5.01k|        vertexNum > (isPent ? NUM_PENT_VERTS : NUM_HEX_VERTS) - 1)
  ------------------
  |  |   85|     52|#define NUM_PENT_VERTS 5
  ------------------
                      vertexNum > (isPent ? NUM_PENT_VERTS : NUM_HEX_VERTS) - 1)
  ------------------
  |  |   83|  4.96k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (177:9): [True: 0, False: 5.01k]
  |  Branch (177:22): [True: 52, False: 4.96k]
  ------------------
  178|      0|        return INVALID_DIGIT;
  179|       |
  180|       |    // Determine the vertex rotations for this cell
  181|  5.01k|    int rotations;
  182|  5.01k|    H3Error err = vertexRotations(origin, &rotations);
  183|  5.01k|    if (err) {
  ------------------
  |  Branch (183:9): [True: 8, False: 5.00k]
  ------------------
  184|      8|        return INVALID_DIGIT;
  185|      8|    }
  186|       |
  187|       |    // Find the appropriate direction, rotating CW if necessary
  188|  5.00k|    return isPent ? vertexNumToDirectionPent[(vertexNum + rotations) %
  ------------------
  |  Branch (188:12): [True: 52, False: 4.95k]
  ------------------
  189|     52|                                             NUM_PENT_VERTS]
  ------------------
  |  |   85|     52|#define NUM_PENT_VERTS 5
  ------------------
  190|  5.00k|                  : vertexNumToDirectionHex[(vertexNum + rotations) %
  191|  4.95k|                                            NUM_HEX_VERTS];
  ------------------
  |  |   83|  4.95k|#define NUM_HEX_VERTS 6
  ------------------
  192|  5.01k|}
cellToVertex:
  212|  3.50k|H3Error H3_EXPORT(cellToVertex)(H3Index cell, int vertexNum, H3Index *out) {
  213|  3.50k|    int cellIsPentagon = H3_EXPORT(isPentagon)(cell);
  ------------------
  |  |   36|  3.50k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  3.50k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  3.50k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  214|  3.50k|    int cellNumVerts = cellIsPentagon ? NUM_PENT_VERTS : NUM_HEX_VERTS;
  ------------------
  |  |   85|    137|#define NUM_PENT_VERTS 5
  ------------------
                  int cellNumVerts = cellIsPentagon ? NUM_PENT_VERTS : NUM_HEX_VERTS;
  ------------------
  |  |   83|  3.36k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (214:24): [True: 137, False: 3.36k]
  ------------------
  215|  3.50k|    int res = H3_GET_RESOLUTION(cell);
  ------------------
  |  |  129|  3.50k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  3.50k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  3.50k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  3.50k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  216|       |
  217|       |    // Check for invalid vertexes
  218|  3.50k|    if (vertexNum < 0 || vertexNum > cellNumVerts - 1) return E_DOMAIN;
  ------------------
  |  Branch (218:9): [True: 162, False: 3.33k]
  |  Branch (218:26): [True: 258, False: 3.08k]
  ------------------
  219|       |
  220|       |    // Default the owner and vertex number to the input cell
  221|  3.08k|    H3Index owner = cell;
  222|  3.08k|    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.08k|    if (res == 0 || H3_GET_INDEX_DIGIT(cell, res) != CENTER_DIGIT) {
  ------------------
  |  |  141|  2.83k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  2.83k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  2.83k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  2.83k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  2.83k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  |  Branch (229:9): [True: 243, False: 2.83k]
  |  Branch (229:21): [True: 2.51k, False: 321]
  ------------------
  230|       |        // Get the left neighbor of the vertex, with its rotations
  231|  2.75k|        Direction left = directionForVertexNum(cell, vertexNum);
  232|  2.75k|        if (left == INVALID_DIGIT) return E_FAILED;
  ------------------
  |  Branch (232:13): [True: 8, False: 2.75k]
  ------------------
  233|  2.75k|        int lRotations = 0;
  234|  2.75k|        H3Index leftNeighbor;
  235|  2.75k|        H3Error leftNeighborError =
  236|  2.75k|            h3NeighborRotations(cell, left, &lRotations, &leftNeighbor);
  237|  2.75k|        if (leftNeighborError) return leftNeighborError;
  ------------------
  |  Branch (237:13): [True: 107, False: 2.64k]
  ------------------
  238|       |        // Set to owner if lowest index
  239|  2.64k|        if (leftNeighbor < owner) owner = leftNeighbor;
  ------------------
  |  Branch (239:13): [True: 1.63k, False: 1.00k]
  ------------------
  240|       |
  241|       |        // As above, skip the right neighbor if the left is known lowest
  242|  2.64k|        if (res == 0 || H3_GET_INDEX_DIGIT(leftNeighbor, res) != CENTER_DIGIT) {
  ------------------
  |  |  141|  2.40k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  2.40k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  2.40k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  2.40k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  2.40k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  |  Branch (242:13): [True: 240, False: 2.40k]
  |  Branch (242:25): [True: 2.01k, False: 389]
  ------------------
  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.25k|            Direction right = directionForVertexNum(
  246|  2.25k|                cell, (vertexNum - 1 + cellNumVerts) % cellNumVerts);
  247|       |            // This case should be unreachable; invalid verts fail earlier
  248|  2.25k|            if (NEVER(right == INVALID_DIGIT)) return E_FAILED;
  ------------------
  |  |  119|  2.25k|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 2.25k]
  |  |  |  Branch (119:19): [True: 0, False: 2.25k]
  |  |  ------------------
  ------------------
  |  Branch (248:17): [Folded, False: 0]
  |  Branch (248:17): [Folded, False: 0]
  ------------------
  249|  2.25k|            int rRotations = 0;
  250|  2.25k|            H3Index rightNeighbor;
  251|  2.25k|            H3Error rightNeighborError =
  252|  2.25k|                h3NeighborRotations(cell, right, &rRotations, &rightNeighbor);
  253|  2.25k|            if (rightNeighborError) return rightNeighborError;
  ------------------
  |  Branch (253:17): [True: 25, False: 2.23k]
  ------------------
  254|       |            // Set to owner if lowest index
  255|  2.23k|            if (rightNeighbor < owner) {
  ------------------
  |  Branch (255:17): [True: 1.04k, False: 1.18k]
  ------------------
  256|  1.04k|                owner = rightNeighbor;
  257|  1.04k|                Direction dir =
  258|  1.04k|                    H3_EXPORT(isPentagon)(owner)
  ------------------
  |  |   36|  1.04k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  1.04k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  1.04k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (258:21): [True: 76, False: 969]
  ------------------
  259|  1.04k|                        ? directionForNeighbor(owner, cell)
  260|  1.04k|                        : DIRECTIONS[(revNeighborDirectionsHex[right] +
  261|    969|                                      rRotations) %
  262|    969|                                     NUM_HEX_VERTS];
  ------------------
  |  |   83|    969|#define NUM_HEX_VERTS 6
  ------------------
  263|  1.04k|                ownerVertexNum = vertexNumForDirection(owner, dir);
  264|  1.04k|            }
  265|  2.23k|        }
  266|       |
  267|       |        // Determine the vertex number for the left neighbor
  268|  2.61k|        if (owner == leftNeighbor) {
  ------------------
  |  Branch (268:13): [True: 1.05k, False: 1.56k]
  ------------------
  269|  1.05k|            int ownerIsPentagon = H3_EXPORT(isPentagon)(owner);
  ------------------
  |  |   36|  1.05k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  1.05k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  1.05k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  270|  1.05k|            Direction dir =
  271|  1.05k|                ownerIsPentagon
  ------------------
  |  Branch (271:17): [True: 52, False: 1.00k]
  ------------------
  272|  1.05k|                    ? directionForNeighbor(owner, cell)
  273|  1.05k|                    : DIRECTIONS[(revNeighborDirectionsHex[left] + lRotations) %
  274|  1.00k|                                 NUM_HEX_VERTS];
  ------------------
  |  |   83|  1.00k|#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.05k|            ownerVertexNum = vertexNumForDirection(owner, dir) + 1;
  279|  1.05k|            if (ownerVertexNum == NUM_HEX_VERTS ||
  ------------------
  |  |   83|  2.10k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (279:17): [True: 165, False: 889]
  ------------------
  280|    889|                (ownerIsPentagon && ownerVertexNum == NUM_PENT_VERTS)) {
  ------------------
  |  |   85|     52|#define NUM_PENT_VERTS 5
  ------------------
  |  Branch (280:18): [True: 52, False: 837]
  |  Branch (280:37): [True: 11, False: 41]
  ------------------
  281|    176|                ownerVertexNum = 0;
  282|    176|            }
  283|  1.05k|        }
  284|  2.61k|    }
  285|       |
  286|       |    // Create the vertex index
  287|  2.94k|    H3Index vertex = owner;
  288|  2.94k|    H3_SET_MODE(vertex, H3_VERTEX_MODE);
  ------------------
  |  |  113|  2.94k|    (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   59|  2.94k|#define H3_MODE_MASK_NEGATIVE (~H3_MODE_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   56|  2.94k|#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   35|  2.94k|#define H3_MODE_OFFSET 59
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   35|  2.94k|#define H3_MODE_OFFSET 59
  |  |  ------------------
  ------------------
  289|  2.94k|    H3_SET_RESERVED_BITS(vertex, ownerVertexNum);
  ------------------
  |  |  149|  2.94k|    (h3) = (((h3)&H3_RESERVED_MASK_NEGATIVE) | \
  |  |  ------------------
  |  |  |  |   77|  2.94k|#define H3_RESERVED_MASK_NEGATIVE (~H3_RESERVED_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   74|  2.94k|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   44|  2.94k|#define H3_RESERVED_OFFSET 56
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  150|  2.94k|            (((uint64_t)(v)) << H3_RESERVED_OFFSET))
  |  |  ------------------
  |  |  |  |   44|  2.94k|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  290|  2.94k|    *out = vertex;
  291|       |
  292|  2.94k|    return E_SUCCESS;
  293|  3.08k|}
cellToVertexes:
  300|    563|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|    563|    bool isPent = H3_EXPORT(isPentagon)(cell);
  ------------------
  |  |   36|    563|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    563|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    563|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  304|  3.26k|    for (int i = 0; i < NUM_HEX_VERTS; i++) {
  ------------------
  |  |   83|  3.26k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (304:21): [True: 2.82k, False: 443]
  ------------------
  305|  2.82k|        if (i == 5 && isPent) {
  ------------------
  |  Branch (305:13): [True: 443, False: 2.38k]
  |  Branch (305:23): [True: 22, False: 421]
  ------------------
  306|     22|            vertexes[i] = H3_NULL;
  ------------------
  |  |   76|     22|#define H3_NULL 0
  ------------------
  307|  2.80k|        } else {
  308|  2.80k|            H3Error cellError = H3_EXPORT(cellToVertex)(cell, i, &vertexes[i]);
  ------------------
  |  |   36|  2.80k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  2.80k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  2.80k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  309|  2.80k|            if (cellError) {
  ------------------
  |  Branch (309:17): [True: 120, False: 2.68k]
  ------------------
  310|    120|                return cellError;
  311|    120|            }
  312|  2.80k|        }
  313|  2.82k|    }
  314|    443|    return E_SUCCESS;
  315|    563|}
vertexToLatLng:
  322|    563|H3Error H3_EXPORT(vertexToLatLng)(H3Index vertex, LatLng *coord) {
  323|       |    // Get the vertex number and owner from the vertex
  324|    563|    int vertexNum = H3_GET_RESERVED_BITS(vertex);
  ------------------
  |  |  156|    563|    ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET)))
  |  |  ------------------
  |  |  |  |   74|    563|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|    563|#define H3_RESERVED_OFFSET 56
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET)))
  |  |  ------------------
  |  |  |  |   44|    563|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  325|    563|    H3Index owner = vertex;
  326|    563|    H3_SET_MODE(owner, H3_CELL_MODE);
  ------------------
  |  |  113|    563|    (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   59|    563|#define H3_MODE_MASK_NEGATIVE (~H3_MODE_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   56|    563|#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   35|    563|#define H3_MODE_OFFSET 59
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   35|    563|#define H3_MODE_OFFSET 59
  |  |  ------------------
  ------------------
  327|    563|    H3_SET_RESERVED_BITS(owner, 0);
  ------------------
  |  |  149|    563|    (h3) = (((h3)&H3_RESERVED_MASK_NEGATIVE) | \
  |  |  ------------------
  |  |  |  |   77|    563|#define H3_RESERVED_MASK_NEGATIVE (~H3_RESERVED_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   74|    563|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   44|    563|#define H3_RESERVED_OFFSET 56
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  150|    563|            (((uint64_t)(v)) << H3_RESERVED_OFFSET))
  |  |  ------------------
  |  |  |  |   44|    563|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  328|       |
  329|       |    // Get the single vertex from the boundary
  330|    563|    CellBoundary gb;
  331|    563|    FaceIJK fijk;
  332|    563|    H3Error fijkError = _h3ToFaceIjk(owner, &fijk);
  333|    563|    if (fijkError) {
  ------------------
  |  Branch (333:9): [True: 7, False: 556]
  ------------------
  334|      7|        return fijkError;
  335|      7|    }
  336|    556|    int res = H3_GET_RESOLUTION(owner);
  ------------------
  |  |  129|    556|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|    556|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|    556|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|    556|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  337|       |
  338|    556|    if (H3_EXPORT(isPentagon)(owner)) {
  ------------------
  |  |   36|    556|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    556|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    556|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (338:9): [True: 22, False: 534]
  ------------------
  339|     22|        _faceIjkPentToCellBoundary(&fijk, res, vertexNum, 1, &gb);
  340|    534|    } else {
  341|    534|        _faceIjkToCellBoundary(&fijk, res, vertexNum, 1, &gb);
  342|    534|    }
  343|       |
  344|       |    // Copy from boundary to output coord
  345|    556|    *coord = gb.verts[0];
  346|    556|    return E_SUCCESS;
  347|    563|}
isValidVertex:
  354|    563|int H3_EXPORT(isValidVertex)(H3Index vertex) {
  355|    563|    if (H3_GET_MODE(vertex) != H3_VERTEX_MODE) {
  ------------------
  |  |  107|    563|#define H3_GET_MODE(h3) ((int)((((h3)&H3_MODE_MASK) >> H3_MODE_OFFSET)))
  |  |  ------------------
  |  |  |  |   56|    563|#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   35|    563|#define H3_MODE_OFFSET 59
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_MODE(h3) ((int)((((h3)&H3_MODE_MASK) >> H3_MODE_OFFSET)))
  |  |  ------------------
  |  |  |  |   35|    563|#define H3_MODE_OFFSET 59
  |  |  ------------------
  ------------------
                  if (H3_GET_MODE(vertex) != H3_VERTEX_MODE) {
  ------------------
  |  |   93|    563|#define H3_VERTEX_MODE 4
  ------------------
  |  Branch (355:9): [True: 322, False: 241]
  ------------------
  356|    322|        return 0;
  357|    322|    }
  358|       |
  359|    241|    int vertexNum = H3_GET_RESERVED_BITS(vertex);
  ------------------
  |  |  156|    241|    ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET)))
  |  |  ------------------
  |  |  |  |   74|    241|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|    241|#define H3_RESERVED_OFFSET 56
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET)))
  |  |  ------------------
  |  |  |  |   44|    241|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  360|    241|    H3Index owner = vertex;
  361|    241|    H3_SET_MODE(owner, H3_CELL_MODE);
  ------------------
  |  |  113|    241|    (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   59|    241|#define H3_MODE_MASK_NEGATIVE (~H3_MODE_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   56|    241|#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   35|    241|#define H3_MODE_OFFSET 59
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   35|    241|#define H3_MODE_OFFSET 59
  |  |  ------------------
  ------------------
  362|    241|    H3_SET_RESERVED_BITS(owner, 0);
  ------------------
  |  |  149|    241|    (h3) = (((h3)&H3_RESERVED_MASK_NEGATIVE) | \
  |  |  ------------------
  |  |  |  |   77|    241|#define H3_RESERVED_MASK_NEGATIVE (~H3_RESERVED_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   74|    241|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   44|    241|#define H3_RESERVED_OFFSET 56
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  150|    241|            (((uint64_t)(v)) << H3_RESERVED_OFFSET))
  |  |  ------------------
  |  |  |  |   44|    241|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  363|       |
  364|    241|    if (!H3_EXPORT(isValidCell)(owner)) {
  ------------------
  |  |   36|    241|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    241|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    241|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (364:9): [True: 107, False: 134]
  ------------------
  365|    107|        return 0;
  366|    107|    }
  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|    134|    H3Index canonical;
  371|    134|    if (H3_EXPORT(cellToVertex)(owner, vertexNum, &canonical)) {
  ------------------
  |  |   36|    134|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    134|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    134|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (371:9): [True: 5, False: 129]
  ------------------
  372|      5|        return 0;
  373|      5|    }
  374|       |
  375|    129|    return vertex == canonical ? 1 : 0;
  ------------------
  |  Branch (375:12): [True: 19, False: 110]
  ------------------
  376|    134|}
vertex.c:vertexRotations:
   53|  7.09k|static H3Error vertexRotations(H3Index cell, int *out) {
   54|       |    // Get the face and other info for the origin
   55|  7.09k|    FaceIJK fijk;
   56|  7.09k|    H3Error err = _h3ToFaceIjk(cell, &fijk);
   57|  7.09k|    if (err) {
  ------------------
  |  Branch (57:9): [True: 8, False: 7.08k]
  ------------------
   58|      8|        return err;
   59|      8|    }
   60|  7.08k|    int baseCell = H3_EXPORT(getBaseCellNumber)(cell);
  ------------------
  |  |   36|  7.08k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  7.08k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  7.08k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   61|  7.08k|    int cellLeadingDigit = _h3LeadingNonZeroDigit(cell);
   62|       |
   63|       |    // get the base cell face
   64|  7.08k|    FaceIJK baseFijk;
   65|  7.08k|    _baseCellToFaceIjk(baseCell, &baseFijk);
   66|       |
   67|  7.08k|    int ccwRot60 = _baseCellToCCWrot60(baseCell, fijk.face);
   68|       |
   69|  7.08k|    if (_isBaseCellPentagon(baseCell)) {
  ------------------
  |  Branch (69:9): [True: 3.10k, False: 3.98k]
  ------------------
   70|       |        // Find the appropriate direction-to-face mapping
   71|  3.10k|        PentagonDirectionFaces dirFaces;
   72|       |        // We never hit the end condition
   73|  3.10k|        int p = 0;
   74|       |        // Don't use a for loop here, for coverage reasons.
   75|  17.8k|        while (ALWAYS(p < NUM_PENTAGONS)) {
  ------------------
  |  |  118|  17.8k|#define ALWAYS(X) ((X) ? 1 : (assert(0), 0))
  |  |  ------------------
  |  |  |  Branch (118:19): [True: 17.8k, False: 0]
  |  |  |  Branch (118:20): [True: 17.8k, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (75:16): [Folded, False: 0]
  |  Branch (75:16): [Folded, False: 0]
  ------------------
   76|  17.8k|            if (pentagonDirectionFaces[p].baseCell == baseCell) {
  ------------------
  |  Branch (76:17): [True: 3.10k, False: 14.7k]
  ------------------
   77|  3.10k|                dirFaces = pentagonDirectionFaces[p];
   78|  3.10k|                break;
   79|  3.10k|            }
   80|  14.7k|            p++;
   81|  14.7k|        }
   82|  3.10k|        if (NEVER(p == NUM_PENTAGONS)) {
  ------------------
  |  |  119|  3.10k|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 3.10k]
  |  |  |  Branch (119:19): [True: 0, False: 3.10k]
  |  |  ------------------
  ------------------
  |  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.10k|        if (fijk.face != baseFijk.face &&
  ------------------
  |  Branch (87:13): [True: 2.53k, False: 572]
  ------------------
   88|  2.53k|            (_isBaseCellPolarPentagon(baseCell) ||
  ------------------
  |  Branch (88:14): [True: 705, False: 1.82k]
  ------------------
   89|  1.82k|             fijk.face ==
  ------------------
  |  Branch (89:14): [True: 531, False: 1.29k]
  ------------------
   90|  1.82k|                 dirFaces.faces[IK_AXES_DIGIT - DIRECTION_INDEX_OFFSET])) {
  ------------------
  |  |   32|  1.82k|#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.10k|        if (cellLeadingDigit == JK_AXES_DIGIT &&
  ------------------
  |  Branch (95:13): [True: 556, False: 2.54k]
  ------------------
   96|    556|            fijk.face ==
  ------------------
  |  Branch (96:13): [True: 210, False: 346]
  ------------------
   97|    556|                dirFaces.faces[IK_AXES_DIGIT - DIRECTION_INDEX_OFFSET]) {
  ------------------
  |  |   32|    556|#define DIRECTION_INDEX_OFFSET 2
  ------------------
   98|       |            // Crosses from JK to IK: Rotate CW
   99|    210|            ccwRot60 = (ccwRot60 + 5) % 6;
  100|  2.89k|        } else if (cellLeadingDigit == IK_AXES_DIGIT &&
  ------------------
  |  Branch (100:20): [True: 707, False: 2.18k]
  ------------------
  101|    707|                   fijk.face ==
  ------------------
  |  Branch (101:20): [True: 82, False: 625]
  ------------------
  102|    707|                       dirFaces.faces[JK_AXES_DIGIT - DIRECTION_INDEX_OFFSET]) {
  ------------------
  |  |   32|    707|#define DIRECTION_INDEX_OFFSET 2
  ------------------
  103|       |            // Crosses from IK to JK: Rotate CCW
  104|     82|            ccwRot60 = (ccwRot60 + 1) % 6;
  105|     82|        }
  106|  3.10k|    }
  107|  7.08k|    *out = ccwRot60;
  108|  7.08k|    return E_SUCCESS;
  109|  7.08k|}

