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

faceijk.c:_ijkToHex2d:
  244|    521|static inline void _ijkToHex2d(const CoordIJK *h, Vec2d *v) {
  245|    521|    int i = h->i - h->k;
  246|    521|    int j = h->j - h->k;
  247|       |
  248|    521|    v->x = i - 0.5 * j;
  249|    521|    v->y = j * M_SQRT3_2;
  ------------------
  |  |   44|    521|#define M_SQRT3_2 0.8660254037844386467637231707529361834714
  ------------------
  250|    521|}
faceijk.c:_ijkRotate60ccw:
  614|  16.4k|static inline void _ijkRotate60ccw(CoordIJK *ijk) {
  615|       |    // unit vector rotations
  616|  16.4k|    CoordIJK iVec = {1, 1, 0};
  617|  16.4k|    CoordIJK jVec = {0, 1, 1};
  618|  16.4k|    CoordIJK kVec = {1, 0, 1};
  619|       |
  620|  16.4k|    _ijkScale(&iVec, ijk->i);
  621|  16.4k|    _ijkScale(&jVec, ijk->j);
  622|  16.4k|    _ijkScale(&kVec, ijk->k);
  623|       |
  624|  16.4k|    _ijkAdd(&iVec, &jVec, ijk);
  625|  16.4k|    _ijkAdd(ijk, &kVec, ijk);
  626|       |
  627|  16.4k|    _ijkNormalize(ijk);
  628|  16.4k|}
faceijk.c:_ijkScale:
  155|  59.9k|static inline void _ijkScale(CoordIJK *c, int factor) {
  156|  59.9k|    c->i *= factor;
  157|  59.9k|    c->j *= factor;
  158|  59.9k|    c->k *= factor;
  159|  59.9k|}
faceijk.c:_ijkAdd:
  129|  45.2k|                           CoordIJK *sum) {
  130|  45.2k|    sum->i = h1->i + h2->i;
  131|  45.2k|    sum->j = h1->j + h2->j;
  132|  45.2k|    sum->k = h1->k + h2->k;
  133|  45.2k|}
faceijk.c:_ijkNormalize:
  207|  26.5k|static inline void _ijkNormalize(CoordIJK *c) {
  208|       |    // remove any negative values
  209|  26.5k|    if (c->i < 0) {
  ------------------
  |  Branch (209:9): [True: 0, False: 26.5k]
  ------------------
  210|      0|        c->j -= c->i;
  211|      0|        c->k -= c->i;
  212|      0|        c->i = 0;
  213|      0|    }
  214|       |
  215|  26.5k|    if (c->j < 0) {
  ------------------
  |  Branch (215:9): [True: 0, False: 26.5k]
  ------------------
  216|      0|        c->i -= c->j;
  217|      0|        c->k -= c->j;
  218|      0|        c->j = 0;
  219|      0|    }
  220|       |
  221|  26.5k|    if (c->k < 0) {
  ------------------
  |  Branch (221:9): [True: 0, False: 26.5k]
  ------------------
  222|      0|        c->i -= c->k;
  223|      0|        c->j -= c->k;
  224|      0|        c->k = 0;
  225|      0|    }
  226|       |
  227|       |    // remove the min value if needed
  228|  26.5k|    int min = c->i;
  229|  26.5k|    if (c->j < min) min = c->j;
  ------------------
  |  Branch (229:9): [True: 11.5k, False: 14.9k]
  ------------------
  230|  26.5k|    if (c->k < min) min = c->k;
  ------------------
  |  Branch (230:9): [True: 9.87k, False: 16.6k]
  ------------------
  231|  26.5k|    if (min > 0) {
  ------------------
  |  Branch (231:9): [True: 25.1k, False: 1.40k]
  ------------------
  232|  25.1k|        c->i -= min;
  233|  25.1k|        c->j -= min;
  234|  25.1k|        c->k -= min;
  235|  25.1k|    }
  236|  26.5k|}
faceijk.c:_downAp3:
  557|    521|static inline void _downAp3(CoordIJK *ijk) {
  558|       |    // res r unit vectors in res r+1
  559|    521|    CoordIJK iVec = {2, 0, 1};
  560|    521|    CoordIJK jVec = {1, 2, 0};
  561|    521|    CoordIJK kVec = {0, 1, 2};
  562|       |
  563|    521|    _ijkScale(&iVec, ijk->i);
  564|    521|    _ijkScale(&jVec, ijk->j);
  565|    521|    _ijkScale(&kVec, ijk->k);
  566|       |
  567|    521|    _ijkAdd(&iVec, &jVec, ijk);
  568|    521|    _ijkAdd(ijk, &kVec, ijk);
  569|       |
  570|    521|    _ijkNormalize(ijk);
  571|    521|}
faceijk.c:_downAp3r:
  579|    521|static inline void _downAp3r(CoordIJK *ijk) {
  580|       |    // res r unit vectors in res r+1
  581|    521|    CoordIJK iVec = {2, 1, 0};
  582|    521|    CoordIJK jVec = {0, 2, 1};
  583|    521|    CoordIJK kVec = {1, 0, 2};
  584|       |
  585|    521|    _ijkScale(&iVec, ijk->i);
  586|    521|    _ijkScale(&jVec, ijk->j);
  587|    521|    _ijkScale(&kVec, ijk->k);
  588|       |
  589|    521|    _ijkAdd(&iVec, &jVec, ijk);
  590|    521|    _ijkAdd(ijk, &kVec, ijk);
  591|       |
  592|    521|    _ijkNormalize(ijk);
  593|    521|}
faceijk.c:_downAp7r:
  534|    368|static inline void _downAp7r(CoordIJK *ijk) {
  535|       |    // res r unit vectors in res r+1
  536|    368|    CoordIJK iVec = {3, 1, 0};
  537|    368|    CoordIJK jVec = {0, 3, 1};
  538|    368|    CoordIJK kVec = {1, 0, 3};
  539|       |
  540|    368|    _ijkScale(&iVec, ijk->i);
  541|    368|    _ijkScale(&jVec, ijk->j);
  542|    368|    _ijkScale(&kVec, ijk->k);
  543|       |
  544|    368|    _ijkAdd(&iVec, &jVec, ijk);
  545|    368|    _ijkAdd(ijk, &kVec, ijk);
  546|       |
  547|    368|    _ijkNormalize(ijk);
  548|    368|}
faceijk.c:_setIJK:
  103|    436|static inline void _setIJK(CoordIJK *ijk, int i, int j, int k) {
  104|    436|    ijk->i = i;
  105|    436|    ijk->j = j;
  106|    436|    ijk->k = k;
  107|    436|}
faceijk.c:_ijkSub:
  143|    436|                           CoordIJK *diff) {
  144|    436|    diff->i = h1->i - h2->i;
  145|    436|    diff->j = h1->j - h2->j;
  146|    436|    diff->k = h1->k - h2->k;
  147|    436|}
faceijk.c:_ijkRotate60cw:
  635|    436|static inline void _ijkRotate60cw(CoordIJK *ijk) {
  636|       |    // unit vector rotations
  637|    436|    CoordIJK iVec = {1, 0, 1};
  638|    436|    CoordIJK jVec = {1, 1, 0};
  639|    436|    CoordIJK kVec = {0, 1, 1};
  640|       |
  641|    436|    _ijkScale(&iVec, ijk->i);
  642|    436|    _ijkScale(&jVec, ijk->j);
  643|    436|    _ijkScale(&kVec, ijk->k);
  644|       |
  645|    436|    _ijkAdd(&iVec, &jVec, ijk);
  646|    436|    _ijkAdd(ijk, &kVec, ijk);
  647|       |
  648|    436|    _ijkNormalize(ijk);
  649|    436|}
h3Index.c:_rotate60ccw:
  656|  7.34k|static inline Direction _rotate60ccw(Direction digit) {
  657|  7.34k|    switch (digit) {
  658|  1.49k|        case K_AXES_DIGIT:
  ------------------
  |  Branch (658:9): [True: 1.49k, False: 5.85k]
  ------------------
  659|  1.49k|            return IK_AXES_DIGIT;
  660|  1.03k|        case IK_AXES_DIGIT:
  ------------------
  |  Branch (660:9): [True: 1.03k, False: 6.31k]
  ------------------
  661|  1.03k|            return I_AXES_DIGIT;
  662|    842|        case I_AXES_DIGIT:
  ------------------
  |  Branch (662:9): [True: 842, False: 6.50k]
  ------------------
  663|    842|            return IJ_AXES_DIGIT;
  664|    911|        case IJ_AXES_DIGIT:
  ------------------
  |  Branch (664:9): [True: 911, False: 6.43k]
  ------------------
  665|    911|            return J_AXES_DIGIT;
  666|  1.38k|        case J_AXES_DIGIT:
  ------------------
  |  Branch (666:9): [True: 1.38k, False: 5.96k]
  ------------------
  667|  1.38k|            return JK_AXES_DIGIT;
  668|  1.53k|        case JK_AXES_DIGIT:
  ------------------
  |  Branch (668:9): [True: 1.53k, False: 5.81k]
  ------------------
  669|  1.53k|            return K_AXES_DIGIT;
  670|    155|        default:
  ------------------
  |  Branch (670:9): [True: 155, False: 7.19k]
  ------------------
  671|    155|            return digit;
  672|  7.34k|    }
  673|  7.34k|}
h3Index.c:_rotate60cw:
  680|  6.38k|static inline Direction _rotate60cw(Direction digit) {
  681|  6.38k|    switch (digit) {
  682|    834|        case K_AXES_DIGIT:
  ------------------
  |  Branch (682:9): [True: 834, False: 5.54k]
  ------------------
  683|    834|            return JK_AXES_DIGIT;
  684|    668|        case JK_AXES_DIGIT:
  ------------------
  |  Branch (684:9): [True: 668, False: 5.71k]
  ------------------
  685|    668|            return J_AXES_DIGIT;
  686|    505|        case J_AXES_DIGIT:
  ------------------
  |  Branch (686:9): [True: 505, False: 5.87k]
  ------------------
  687|    505|            return IJ_AXES_DIGIT;
  688|    402|        case IJ_AXES_DIGIT:
  ------------------
  |  Branch (688:9): [True: 402, False: 5.98k]
  ------------------
  689|    402|            return I_AXES_DIGIT;
  690|    659|        case I_AXES_DIGIT:
  ------------------
  |  Branch (690:9): [True: 659, False: 5.72k]
  ------------------
  691|    659|            return IK_AXES_DIGIT;
  692|  1.15k|        case IK_AXES_DIGIT:
  ------------------
  |  Branch (692:9): [True: 1.15k, False: 5.22k]
  ------------------
  693|  1.15k|            return K_AXES_DIGIT;
  694|  2.16k|        default:
  ------------------
  |  Branch (694:9): [True: 2.16k, False: 4.22k]
  ------------------
  695|  2.16k|            return digit;
  696|  6.38k|    }
  697|  6.38k|}
h3Index.c:_downAp7:
  512|  35.6k|static inline void _downAp7(CoordIJK *ijk) {
  513|       |    // res r unit vectors in res r+1
  514|  35.6k|    CoordIJK iVec = {3, 0, 1};
  515|  35.6k|    CoordIJK jVec = {1, 3, 0};
  516|  35.6k|    CoordIJK kVec = {0, 1, 3};
  517|       |
  518|  35.6k|    _ijkScale(&iVec, ijk->i);
  519|  35.6k|    _ijkScale(&jVec, ijk->j);
  520|  35.6k|    _ijkScale(&kVec, ijk->k);
  521|       |
  522|  35.6k|    _ijkAdd(&iVec, &jVec, ijk);
  523|  35.6k|    _ijkAdd(ijk, &kVec, ijk);
  524|       |
  525|  35.6k|    _ijkNormalize(ijk);
  526|  35.6k|}
h3Index.c:_ijkScale:
  155|   213k|static inline void _ijkScale(CoordIJK *c, int factor) {
  156|   213k|    c->i *= factor;
  157|   213k|    c->j *= factor;
  158|   213k|    c->k *= factor;
  159|   213k|}
h3Index.c:_ijkAdd:
  129|   192k|                           CoordIJK *sum) {
  130|   192k|    sum->i = h1->i + h2->i;
  131|   192k|    sum->j = h1->j + h2->j;
  132|   192k|    sum->k = h1->k + h2->k;
  133|   192k|}
h3Index.c:_upAp7r:
  494|  2.69k|static inline void _upAp7r(CoordIJK *ijk) {
  495|       |    // convert to CoordIJ
  496|  2.69k|    int i = ijk->i - ijk->k;
  497|  2.69k|    int j = ijk->j - ijk->k;
  498|       |
  499|  2.69k|    ijk->i = (int)lround((2 * i + j) * M_ONESEVENTH);
  ------------------
  |  |   54|  2.69k|#define M_ONESEVENTH 0.14285714285714285714285714285714285
  ------------------
  500|  2.69k|    ijk->j = (int)lround((3 * j - i) * M_ONESEVENTH);
  ------------------
  |  |   54|  2.69k|#define M_ONESEVENTH 0.14285714285714285714285714285714285
  ------------------
  501|  2.69k|    ijk->k = 0;
  502|  2.69k|    _ijkNormalize(ijk);
  503|  2.69k|}
h3Index.c:_downAp7r:
  534|  35.4k|static inline void _downAp7r(CoordIJK *ijk) {
  535|       |    // res r unit vectors in res r+1
  536|  35.4k|    CoordIJK iVec = {3, 1, 0};
  537|  35.4k|    CoordIJK jVec = {0, 3, 1};
  538|  35.4k|    CoordIJK kVec = {1, 0, 3};
  539|       |
  540|  35.4k|    _ijkScale(&iVec, ijk->i);
  541|  35.4k|    _ijkScale(&jVec, ijk->j);
  542|  35.4k|    _ijkScale(&kVec, ijk->k);
  543|       |
  544|  35.4k|    _ijkAdd(&iVec, &jVec, ijk);
  545|  35.4k|    _ijkAdd(ijk, &kVec, ijk);
  546|       |
  547|  35.4k|    _ijkNormalize(ijk);
  548|  35.4k|}
h3Index.c:_ijkNormalize:
  207|   123k|static inline void _ijkNormalize(CoordIJK *c) {
  208|       |    // remove any negative values
  209|   123k|    if (c->i < 0) {
  ------------------
  |  Branch (209:9): [True: 839, False: 122k]
  ------------------
  210|    839|        c->j -= c->i;
  211|    839|        c->k -= c->i;
  212|    839|        c->i = 0;
  213|    839|    }
  214|       |
  215|   123k|    if (c->j < 0) {
  ------------------
  |  Branch (215:9): [True: 952, False: 122k]
  ------------------
  216|    952|        c->i -= c->j;
  217|    952|        c->k -= c->j;
  218|    952|        c->j = 0;
  219|    952|    }
  220|       |
  221|   123k|    if (c->k < 0) {
  ------------------
  |  Branch (221:9): [True: 0, False: 123k]
  ------------------
  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|   123k|    int min = c->i;
  229|   123k|    if (c->j < min) min = c->j;
  ------------------
  |  Branch (229:9): [True: 88.7k, False: 35.0k]
  ------------------
  230|   123k|    if (c->k < min) min = c->k;
  ------------------
  |  Branch (230:9): [True: 37.4k, False: 86.3k]
  ------------------
  231|   123k|    if (min > 0) {
  ------------------
  |  Branch (231:9): [True: 81.9k, False: 41.7k]
  ------------------
  232|  81.9k|        c->i -= min;
  233|  81.9k|        c->j -= min;
  234|  81.9k|        c->k -= min;
  235|  81.9k|    }
  236|   123k|}
h3Index.c:_neighbor:
  602|  66.2k|static inline void _neighbor(CoordIJK *ijk, Direction digit) {
  603|  66.2k|    if (digit > CENTER_DIGIT && digit < NUM_DIGITS) {
  ------------------
  |  Branch (603:9): [True: 52.8k, False: 13.4k]
  |  Branch (603:33): [True: 49.9k, False: 2.92k]
  ------------------
  604|  49.9k|        _ijkAdd(ijk, &UNIT_VECS[digit], ijk);
  605|  49.9k|        _ijkNormalize(ijk);
  606|  49.9k|    }
  607|  66.2k|}

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

h3NeighborRotations:
  450|  5.10k|                            H3Index *out) {
  451|  5.10k|    H3Index current = origin;
  452|       |
  453|  5.10k|    if (dir < CENTER_DIGIT || dir >= INVALID_DIGIT) {
  ------------------
  |  Branch (453:9): [True: 0, False: 5.10k]
  |  Branch (453:31): [True: 0, False: 5.10k]
  ------------------
  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.10k|    *rotations = *rotations % 6;
  459|  5.10k|    for (int i = 0; i < *rotations; i++) {
  ------------------
  |  Branch (459:21): [True: 0, False: 5.10k]
  ------------------
  460|      0|        dir = _rotate60ccw(dir);
  461|      0|    }
  462|       |
  463|  5.10k|    int newRotations = 0;
  464|  5.10k|    int oldBaseCell = H3_GET_BASE_CELL(current);
  ------------------
  |  |  118|  5.10k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  5.10k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  5.10k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  5.10k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  465|  5.10k|    if (NEVER(oldBaseCell < 0) || oldBaseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |  119|  10.2k|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 5.10k]
  |  |  |  Branch (119:19): [True: 0, False: 5.10k]
  |  |  ------------------
  ------------------
                  if (NEVER(oldBaseCell < 0) || oldBaseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |   81|  5.10k|#define NUM_BASE_CELLS 122
  ------------------
  |  Branch (465:9): [Folded, False: 0]
  |  Branch (465:9): [Folded, False: 0]
  |  Branch (465:35): [True: 0, False: 5.10k]
  ------------------
  466|       |        // Base cells less than zero can not be represented in an index
  467|      0|        return E_CELL_INVALID;
  468|      0|    }
  469|  5.10k|    Direction oldLeadingDigit = _h3LeadingNonZeroDigit(current);
  470|       |
  471|       |    // Adjust the indexing digits and, if needed, the base cell.
  472|  5.10k|    int r = H3_GET_RESOLUTION(current) - 1;
  ------------------
  |  |  129|  5.10k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  5.10k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  5.10k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  5.10k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  473|  14.8k|    while (true) {
  ------------------
  |  Branch (473:12): [True: 14.8k, Folded]
  ------------------
  474|  14.8k|        if (r == -1) {
  ------------------
  |  Branch (474:13): [True: 1.32k, False: 13.4k]
  ------------------
  475|  1.32k|            H3_SET_BASE_CELL(current, baseCellNeighbors[oldBaseCell][dir]);
  ------------------
  |  |  124|  1.32k|    (h3) = (((h3)&H3_BC_MASK_NEGATIVE) | (((uint64_t)(bc)) << H3_BC_OFFSET))
  |  |  ------------------
  |  |  |  |   65|  1.32k|#define H3_BC_MASK_NEGATIVE (~H3_BC_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   62|  1.32k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|  1.32k|#define H3_BC_OFFSET 45
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (h3) = (((h3)&H3_BC_MASK_NEGATIVE) | (((uint64_t)(bc)) << H3_BC_OFFSET))
  |  |  ------------------
  |  |  |  |   38|  1.32k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  476|  1.32k|            newRotations = baseCellNeighbor60CCWRots[oldBaseCell][dir];
  477|       |
  478|  1.32k|            if (H3_GET_BASE_CELL(current) == INVALID_BASE_CELL) {
  ------------------
  |  |  118|  1.32k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  1.32k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  1.32k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  1.32k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
                          if (H3_GET_BASE_CELL(current) == INVALID_BASE_CELL) {
  ------------------
  |  |   38|  1.32k|#define INVALID_BASE_CELL 127
  ------------------
  |  Branch (478:17): [True: 50, False: 1.27k]
  ------------------
  479|       |                // Adjust for the deleted k vertex at the base cell level.
  480|       |                // This edge actually borders a different neighbor.
  481|     50|                H3_SET_BASE_CELL(current,
  ------------------
  |  |  124|     50|    (h3) = (((h3)&H3_BC_MASK_NEGATIVE) | (((uint64_t)(bc)) << H3_BC_OFFSET))
  |  |  ------------------
  |  |  |  |   65|     50|#define H3_BC_MASK_NEGATIVE (~H3_BC_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   62|     50|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   38|     50|#define H3_BC_OFFSET 45
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (h3) = (((h3)&H3_BC_MASK_NEGATIVE) | (((uint64_t)(bc)) << H3_BC_OFFSET))
  |  |  ------------------
  |  |  |  |   38|     50|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  482|     50|                                 baseCellNeighbors[oldBaseCell][IK_AXES_DIGIT]);
  483|     50|                newRotations =
  484|     50|                    baseCellNeighbor60CCWRots[oldBaseCell][IK_AXES_DIGIT];
  485|       |
  486|       |                // perform the adjustment for the k-subsequence we're skipping
  487|       |                // over.
  488|     50|                current = _h3Rotate60ccw(current);
  489|     50|                *rotations = *rotations + 1;
  490|     50|            }
  491|       |
  492|  1.32k|            break;
  493|  13.4k|        } else {
  494|  13.4k|            Direction oldDigit = H3_GET_INDEX_DIGIT(current, r + 1);
  ------------------
  |  |  141|  13.4k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  13.4k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  13.4k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  13.4k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  13.4k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  495|  13.4k|            Direction nextDir;
  496|  13.4k|            if (oldDigit == INVALID_DIGIT) {
  ------------------
  |  Branch (496:17): [True: 100, False: 13.3k]
  ------------------
  497|       |                // Only possible on invalid input
  498|    100|                return E_CELL_INVALID;
  499|  13.3k|            } else if (isResolutionClassIII(r + 1)) {
  ------------------
  |  Branch (499:24): [True: 7.69k, False: 5.68k]
  ------------------
  500|  7.69k|                H3_SET_INDEX_DIGIT(current, r + 1, NEW_DIGIT_II[oldDigit][dir]);
  ------------------
  |  |  162|  7.69k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  7.69k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  7.69k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  7.69k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  7.69k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  7.69k|            (((uint64_t)(digit))                                            \
  |  |  165|  7.69k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  7.69k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  7.69k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  ------------------
  501|  7.69k|                nextDir = NEW_ADJUSTMENT_II[oldDigit][dir];
  502|  7.69k|            } else {
  503|  5.68k|                H3_SET_INDEX_DIGIT(current, r + 1,
  ------------------
  |  |  162|  5.68k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  5.68k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  5.68k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  5.68k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  5.68k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  5.68k|            (((uint64_t)(digit))                                            \
  |  |  165|  5.68k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  5.68k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  5.68k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  ------------------
  504|  5.68k|                                   NEW_DIGIT_III[oldDigit][dir]);
  505|  5.68k|                nextDir = NEW_ADJUSTMENT_III[oldDigit][dir];
  506|  5.68k|            }
  507|       |
  508|  13.3k|            if (nextDir != CENTER_DIGIT) {
  ------------------
  |  Branch (508:17): [True: 9.70k, False: 3.68k]
  ------------------
  509|  9.70k|                dir = nextDir;
  510|  9.70k|                r--;
  511|  9.70k|            } else {
  512|       |                // No more adjustment to perform
  513|  3.68k|                break;
  514|  3.68k|            }
  515|  13.3k|        }
  516|  14.8k|    }
  517|       |
  518|  5.00k|    int newBaseCell = H3_GET_BASE_CELL(current);
  ------------------
  |  |  118|  5.00k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  5.00k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  5.00k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  5.00k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  519|  5.00k|    if (_isBaseCellPentagon(newBaseCell)) {
  ------------------
  |  Branch (519:9): [True: 2.51k, False: 2.48k]
  ------------------
  520|  2.51k|        int alreadyAdjustedKSubsequence = 0;
  521|       |
  522|       |        // force rotation out of missing k-axes sub-sequence
  523|  2.51k|        if (_h3LeadingNonZeroDigit(current) == K_AXES_DIGIT) {
  ------------------
  |  Branch (523:13): [True: 200, False: 2.31k]
  ------------------
  524|    200|            if (oldBaseCell != newBaseCell) {
  ------------------
  |  Branch (524:17): [True: 57, False: 143]
  ------------------
  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|     57|                if (ALWAYS(_baseCellIsCwOffset(
  ------------------
  |  |  118|     57|#define ALWAYS(X) ((X) ? 1 : (assert(0), 0))
  |  |  ------------------
  |  |  |  Branch (118:19): [True: 57, False: 0]
  |  |  |  Branch (118:20): [True: 57, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (531:21): [Folded, False: 0]
  |  Branch (531:21): [Folded, False: 0]
  ------------------
  532|     57|                        newBaseCell,
  533|     57|                        baseCellData[oldBaseCell].homeFijk.face))) {
  534|     57|                    current = _h3Rotate60cw(current);
  535|     57|                } else {
  536|       |                    // See cwOffsetPent in testGridDisk.c for why this is
  537|       |                    // unreachable.
  538|      0|                    current = _h3Rotate60ccw(current);
  539|      0|                }
  540|     57|                alreadyAdjustedKSubsequence = 1;
  541|    143|            } else {
  542|       |                // In this case, we traversed into the deleted
  543|       |                // k subsequence from within the same pentagon
  544|       |                // base cell.
  545|    143|                if (oldLeadingDigit == CENTER_DIGIT) {
  ------------------
  |  Branch (545:21): [True: 0, False: 143]
  ------------------
  546|       |                    // Undefined: the k direction is deleted from here
  547|      0|                    return E_PENTAGON;
  548|    143|                } else if (oldLeadingDigit == JK_AXES_DIGIT) {
  ------------------
  |  Branch (548:28): [True: 48, False: 95]
  ------------------
  549|       |                    // Rotate out of the deleted k subsequence
  550|       |                    // We also need an additional change to the direction we're
  551|       |                    // moving in
  552|     48|                    current = _h3Rotate60ccw(current);
  553|     48|                    *rotations = *rotations + 1;
  554|     95|                } else if (oldLeadingDigit == IK_AXES_DIGIT) {
  ------------------
  |  Branch (554:28): [True: 62, False: 33]
  ------------------
  555|       |                    // Rotate out of the deleted k subsequence
  556|       |                    // We also need an additional change to the direction we're
  557|       |                    // moving in
  558|     62|                    current = _h3Rotate60cw(current);
  559|     62|                    *rotations = *rotations + 5;
  560|     62|                } else {
  561|       |                    // TODO: Should never occur, but is reachable by fuzzer
  562|     33|                    return E_FAILED;
  563|     33|                }
  564|    143|            }
  565|    200|        }
  566|       |
  567|  2.99k|        for (int i = 0; i < newRotations; i++)
  ------------------
  |  Branch (567:25): [True: 518, False: 2.48k]
  ------------------
  568|    518|            current = _h3RotatePent60ccw(current);
  569|       |
  570|       |        // Account for differing orientation of the base cells (this edge
  571|       |        // might not follow properties of some other edges.)
  572|  2.48k|        if (oldBaseCell != newBaseCell) {
  ------------------
  |  Branch (572:13): [True: 344, False: 2.13k]
  ------------------
  573|    344|            if (_isBaseCellPolarPentagon(newBaseCell)) {
  ------------------
  |  Branch (573:17): [True: 191, False: 153]
  ------------------
  574|       |                // 'polar' base cells behave differently because they have all
  575|       |                // i neighbors.
  576|    191|                if (oldBaseCell != 118 && oldBaseCell != 8 &&
  ------------------
  |  Branch (576:21): [True: 168, False: 23]
  |  Branch (576:43): [True: 135, False: 33]
  ------------------
  577|    135|                    _h3LeadingNonZeroDigit(current) != JK_AXES_DIGIT) {
  ------------------
  |  Branch (577:21): [True: 95, False: 40]
  ------------------
  578|     95|                    *rotations = *rotations + 1;
  579|     95|                }
  580|    191|            } else if (_h3LeadingNonZeroDigit(current) == IK_AXES_DIGIT &&
  ------------------
  |  Branch (580:24): [True: 46, False: 107]
  ------------------
  581|     46|                       !alreadyAdjustedKSubsequence) {
  ------------------
  |  Branch (581:24): [True: 25, False: 21]
  ------------------
  582|       |                // account for distortion introduced to the 5 neighbor by the
  583|       |                // deleted k subsequence.
  584|     25|                *rotations = *rotations + 1;
  585|     25|            }
  586|    344|        }
  587|  2.48k|    } else {
  588|  4.15k|        for (int i = 0; i < newRotations; i++)
  ------------------
  |  Branch (588:25): [True: 1.66k, False: 2.48k]
  ------------------
  589|  1.66k|            current = _h3Rotate60ccw(current);
  590|  2.48k|    }
  591|       |
  592|  4.97k|    *rotations = (*rotations + newRotations) % 6;
  593|  4.97k|    *out = current;
  594|       |
  595|  4.97k|    return E_SUCCESS;
  596|  5.00k|}
directionForNeighbor:
  606|    126|Direction directionForNeighbor(H3Index origin, H3Index destination) {
  607|    126|    bool isPent = H3_EXPORT(isPentagon)(origin);
  ------------------
  |  |   36|    126|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    126|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    126|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  608|       |    // Checks each neighbor, in order, to determine which direction the
  609|       |    // destination neighbor is located. Skips CENTER_DIGIT since that
  610|       |    // would be the origin; skips deleted K direction for pentagons.
  611|    126|    for (Direction direction = isPent ? J_AXES_DIGIT : K_AXES_DIGIT;
  ------------------
  |  Branch (611:32): [True: 126, False: 0]
  ------------------
  612|    544|         direction < NUM_DIGITS; direction++) {
  ------------------
  |  Branch (612:10): [True: 523, False: 21]
  ------------------
  613|    523|        H3Index neighbor;
  614|    523|        int rotations = 0;
  615|    523|        H3Error neighborError =
  616|    523|            h3NeighborRotations(origin, direction, &rotations, &neighbor);
  617|    523|        if (!neighborError && neighbor == destination) {
  ------------------
  |  Branch (617:13): [True: 523, False: 0]
  |  Branch (617:31): [True: 105, False: 418]
  ------------------
  618|    105|            return direction;
  619|    105|        }
  620|    523|    }
  621|     21|    return INVALID_DIGIT;
  622|    126|}

_isBaseCellPentagon:
  824|  47.5k|int _isBaseCellPentagon(int baseCell) {
  825|  47.5k|    if (baseCell < 0 || baseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |   81|  47.5k|#define NUM_BASE_CELLS 122
  ------------------
  |  Branch (825:9): [True: 0, False: 47.5k]
  |  Branch (825:25): [True: 33, False: 47.5k]
  ------------------
  826|       |        // Base cells less than zero can not be represented in an index
  827|     33|        return false;
  828|     33|    }
  829|  47.5k|    return baseCellData[baseCell].isPentagon;
  830|  47.5k|}
_isBaseCellPolarPentagon:
  834|  2.62k|bool _isBaseCellPolarPentagon(int baseCell) {
  835|  2.62k|    return baseCell == 4 || baseCell == 117;
  ------------------
  |  Branch (835:12): [True: 629, False: 1.99k]
  |  Branch (835:29): [True: 311, False: 1.68k]
  ------------------
  836|  2.62k|}
_baseCellToFaceIjk:
  866|  6.43k|void _baseCellToFaceIjk(int baseCell, FaceIJK *h) {
  867|  6.43k|    *h = baseCellData[baseCell].homeFijk;
  868|  6.43k|}
_baseCellToCCWrot60:
  877|  6.43k|int _baseCellToCCWrot60(int baseCell, int face) {
  878|  6.43k|    if (face < 0 || face > NUM_ICOSA_FACES) return INVALID_ROTATIONS;
  ------------------
  |  |   79|  6.43k|#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: 6.43k]
  |  Branch (878:21): [True: 0, False: 6.43k]
  ------------------
  879|  10.9k|    for (int i = 0; i < 3; i++) {
  ------------------
  |  Branch (879:21): [True: 10.9k, False: 0]
  ------------------
  880|  27.7k|        for (int j = 0; j < 3; j++) {
  ------------------
  |  Branch (880:25): [True: 23.2k, False: 4.51k]
  ------------------
  881|  75.9k|            for (int k = 0; k < 3; k++) {
  ------------------
  |  Branch (881:29): [True: 59.1k, False: 16.7k]
  ------------------
  882|  59.1k|                if (faceIjkBaseCells[face][i][j][k].baseCell == baseCell) {
  ------------------
  |  Branch (882:21): [True: 6.43k, False: 52.7k]
  ------------------
  883|  6.43k|                    return faceIjkBaseCells[face][i][j][k].ccwRot60;
  884|  6.43k|                }
  885|  59.1k|            }
  886|  23.2k|        }
  887|  10.9k|    }
  888|      0|    return INVALID_ROTATIONS;
  ------------------
  |  |   49|      0|#define INVALID_ROTATIONS -1
  ------------------
  889|  6.43k|}
_baseCellIsCwOffset:
  893|     57|bool _baseCellIsCwOffset(int baseCell, int testFace) {
  894|     57|    return baseCellData[baseCell].cwOffsetPent[0] == testFace ||
  ------------------
  |  Branch (894:12): [True: 29, False: 28]
  ------------------
  895|     28|           baseCellData[baseCell].cwOffsetPent[1] == testFace;
  ------------------
  |  Branch (895:12): [True: 28, False: 0]
  ------------------
  896|     57|}

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

getBaseCellNumber:
   98|  6.43k|int H3_EXPORT(getBaseCellNumber)(H3Index h) { return H3_GET_BASE_CELL(h); }
  ------------------
  |  |  118|  6.43k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  6.43k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  6.43k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  6.43k|#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: 1, False: 234]
  ------------------
  373|       |
  374|    234|    if (_hasAny7UptoRes(h, res)) return false;
  ------------------
  |  Branch (374:9): [True: 35, False: 199]
  ------------------
  375|    199|    if (!_hasAll7AfterRes(h, res)) return false;
  ------------------
  |  Branch (375:9): [True: 64, False: 135]
  ------------------
  376|    135|    if (_hasDeletedSubsequence(h, bc)) return false;
  ------------------
  |  Branch (376:9): [True: 4, False: 131]
  ------------------
  377|       |
  378|       |    // If no disqualifications were identified, the index is a valid H3 cell.
  379|    131|    return true;
  380|    135|}
isPentagon:
  842|  12.7k|int H3_EXPORT(isPentagon)(H3Index h) {
  843|  12.7k|    return _isBaseCellPentagon(H3_GET_BASE_CELL(h)) &&
  ------------------
  |  |  118|  12.7k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  12.7k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  12.7k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  12.7k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  |  Branch (843:12): [True: 5.80k, False: 6.94k]
  ------------------
  844|  5.80k|           !_h3LeadingNonZeroDigit(h);
  ------------------
  |  Branch (844:12): [True: 539, False: 5.26k]
  ------------------
  845|  12.7k|}
_h3LeadingNonZeroDigit:
  852|  26.7k|Direction _h3LeadingNonZeroDigit(H3Index h) {
  853|  75.9k|    for (int r = 1; r <= H3_GET_RESOLUTION(h); r++)
  ------------------
  |  |  129|  75.9k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  75.9k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  75.9k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  75.9k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (853:21): [True: 72.8k, False: 3.11k]
  ------------------
  854|  72.8k|        if (H3_GET_INDEX_DIGIT(h, r)) return H3_GET_INDEX_DIGIT(h, r);
  ------------------
  |  |  141|  72.8k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  72.8k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  72.8k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  |  Branch (141:5): [True: 23.6k, False: 49.1k]
  |  |  ------------------
  |  |  142|  72.8k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  72.8k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
                      if (H3_GET_INDEX_DIGIT(h, r)) return H3_GET_INDEX_DIGIT(h, r);
  ------------------
  |  |  141|  23.6k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  23.6k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  23.6k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  23.6k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  23.6k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  855|       |
  856|       |    // if we're here it's all 0's
  857|  3.11k|    return CENTER_DIGIT;
  858|  26.7k|}
_h3RotatePent60ccw:
  864|    518|H3Index _h3RotatePent60ccw(H3Index h) {
  865|       |    // rotate in place; skips any leading 1 digits (k-axis)
  866|       |
  867|    518|    int foundFirstNonZeroDigit = 0;
  868|  3.19k|    for (int r = 1, res = H3_GET_RESOLUTION(h); r <= res; r++) {
  ------------------
  |  |  129|    518|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|    518|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|    518|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|    518|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (868:49): [True: 2.68k, False: 518]
  ------------------
  869|       |        // rotate this digit
  870|  2.68k|        H3_SET_INDEX_DIGIT(h, r, _rotate60ccw(H3_GET_INDEX_DIGIT(h, r)));
  ------------------
  |  |  162|  2.68k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  2.68k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  2.68k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  2.68k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  2.68k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  2.68k|            (((uint64_t)(digit))                                            \
  |  |  165|  2.68k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  2.68k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  2.68k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  ------------------
  871|       |
  872|       |        // look for the first non-zero digit so we
  873|       |        // can adjust for deleted k-axes sequence
  874|       |        // if necessary
  875|  2.68k|        if (!foundFirstNonZeroDigit && H3_GET_INDEX_DIGIT(h, r) != 0) {
  ------------------
  |  |  141|    415|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|    415|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|    415|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|    415|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|    415|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  |  Branch (875:13): [True: 415, False: 2.26k]
  |  Branch (875:40): [True: 415, False: 0]
  ------------------
  876|    415|            foundFirstNonZeroDigit = 1;
  877|       |
  878|       |            // adjust for deleted k-axes sequence
  879|    415|            if (_h3LeadingNonZeroDigit(h) == K_AXES_DIGIT)
  ------------------
  |  Branch (879:17): [True: 135, False: 280]
  ------------------
  880|    135|                h = _h3Rotate60ccw(h);
  881|    415|        }
  882|  2.68k|    }
  883|    518|    return h;
  884|    518|}
_h3Rotate60ccw:
  915|  1.89k|H3Index _h3Rotate60ccw(H3Index h) {
  916|  6.56k|    for (int r = 1, res = H3_GET_RESOLUTION(h); r <= res; r++) {
  ------------------
  |  |  129|  1.89k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  1.89k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  1.89k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  1.89k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (916:49): [True: 4.66k, False: 1.89k]
  ------------------
  917|  4.66k|        Direction oldDigit = H3_GET_INDEX_DIGIT(h, r);
  ------------------
  |  |  141|  4.66k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  4.66k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  4.66k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  4.66k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  4.66k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  918|  4.66k|        H3_SET_INDEX_DIGIT(h, r, _rotate60ccw(oldDigit));
  ------------------
  |  |  162|  4.66k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  4.66k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  4.66k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  4.66k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  4.66k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  4.66k|            (((uint64_t)(digit))                                            \
  |  |  165|  4.66k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  4.66k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  4.66k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  ------------------
  919|  4.66k|    }
  920|       |
  921|  1.89k|    return h;
  922|  1.89k|}
_h3Rotate60cw:
  928|    687|H3Index _h3Rotate60cw(H3Index h) {
  929|  7.07k|    for (int r = 1, res = H3_GET_RESOLUTION(h); r <= res; r++) {
  ------------------
  |  |  129|    687|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|    687|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|    687|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|    687|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (929:49): [True: 6.38k, False: 687]
  ------------------
  930|  6.38k|        H3_SET_INDEX_DIGIT(h, r, _rotate60cw(H3_GET_INDEX_DIGIT(h, r)));
  ------------------
  |  |  162|  6.38k|    (h3) = (((h3) & ~((H3_DIGIT_MASK                                        \
  |  |  ------------------
  |  |  |  |   80|  6.38k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  |  |  163|  6.38k|                       << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   76|  6.38k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                                      << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))) | \
  |  |  ------------------
  |  |  |  |   47|  6.38k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  164|  6.38k|            (((uint64_t)(digit))                                            \
  |  |  165|  6.38k|             << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   76|  6.38k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                            << ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)))
  |  |  ------------------
  |  |  |  |   47|  6.38k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  ------------------
  931|  6.38k|    }
  932|       |
  933|    687|    return h;
  934|    687|}
_h3ToFaceIjkWithInitializedFijk:
 1087|  6.95k|int _h3ToFaceIjkWithInitializedFijk(H3Index h, FaceIJK *fijk) {
 1088|  6.95k|    CoordIJK *ijk = &fijk->coord;
 1089|  6.95k|    int res = H3_GET_RESOLUTION(h);
  ------------------
  |  |  129|  6.95k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  6.95k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  6.95k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  6.95k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
 1090|       |
 1091|       |    // center base cell hierarchy is entirely on this face
 1092|  6.95k|    int possibleOverage = 1;
 1093|  6.95k|    if (!_isBaseCellPentagon(H3_GET_BASE_CELL(h)) &&
  ------------------
  |  |  118|  6.95k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  6.95k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  6.95k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  6.95k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
  |  Branch (1093:9): [True: 3.84k, False: 3.10k]
  ------------------
 1094|  3.84k|        (res == 0 ||
  ------------------
  |  Branch (1094:10): [True: 668, False: 3.18k]
  ------------------
 1095|  3.18k|         (fijk->coord.i == 0 && fijk->coord.j == 0 && fijk->coord.k == 0)))
  ------------------
  |  Branch (1095:11): [True: 1.71k, False: 1.46k]
  |  Branch (1095:33): [True: 617, False: 1.09k]
  |  Branch (1095:55): [True: 197, False: 420]
  ------------------
 1096|    865|        possibleOverage = 0;
 1097|       |
 1098|  73.2k|    for (int r = 1; r <= res; r++) {
  ------------------
  |  Branch (1098:21): [True: 66.2k, False: 6.95k]
  ------------------
 1099|  66.2k|        if (isResolutionClassIII(r)) {
  ------------------
  |  Branch (1099:13): [True: 35.6k, False: 30.6k]
  ------------------
 1100|       |            // Class III == rotate ccw
 1101|  35.6k|            _downAp7(ijk);
 1102|  35.6k|        } else {
 1103|       |            // Class II == rotate cw
 1104|  30.6k|            _downAp7r(ijk);
 1105|  30.6k|        }
 1106|       |
 1107|  66.2k|        _neighbor(ijk, H3_GET_INDEX_DIGIT(h, r));
  ------------------
  |  |  141|  66.2k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  66.2k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  66.2k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  66.2k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  66.2k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
 1108|  66.2k|    }
 1109|       |
 1110|  6.95k|    return possibleOverage;
 1111|  6.95k|}
_h3ToFaceIjk:
 1118|  6.96k|H3Error _h3ToFaceIjk(H3Index h, FaceIJK *fijk) {
 1119|  6.96k|    int baseCell = H3_GET_BASE_CELL(h);
  ------------------
  |  |  118|  6.96k|#define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   62|  6.96k|#define H3_BC_MASK ((uint64_t)(127) << H3_BC_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   38|  6.96k|#define H3_BC_OFFSET 45
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_BASE_CELL(h3) ((int)((((h3)&H3_BC_MASK) >> H3_BC_OFFSET)))
  |  |  ------------------
  |  |  |  |   38|  6.96k|#define H3_BC_OFFSET 45
  |  |  ------------------
  ------------------
 1120|  6.96k|    if (NEVER(baseCell < 0) || baseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |  119|  13.9k|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 6.96k]
  |  |  |  Branch (119:19): [True: 0, False: 6.96k]
  |  |  ------------------
  ------------------
                  if (NEVER(baseCell < 0) || baseCell >= NUM_BASE_CELLS) {
  ------------------
  |  |   81|  6.96k|#define NUM_BASE_CELLS 122
  ------------------
  |  Branch (1120:9): [Folded, False: 0]
  |  Branch (1120:9): [Folded, False: 0]
  |  Branch (1120:32): [True: 11, False: 6.95k]
  ------------------
 1121|       |        // Base cells less than zero can not be represented in an index
 1122|       |        // To prevent reading uninitialized memory, we zero the output.
 1123|     11|        fijk->face = 0;
 1124|     11|        fijk->coord.i = fijk->coord.j = fijk->coord.k = 0;
 1125|     11|        return E_CELL_INVALID;
 1126|     11|    }
 1127|       |    // adjust for the pentagonal missing sequence; all of sub-sequence 5 needs
 1128|       |    // to be adjusted (and some of sub-sequence 4 below)
 1129|  6.95k|    if (_isBaseCellPentagon(baseCell) && _h3LeadingNonZeroDigit(h) == 5)
  ------------------
  |  Branch (1129:9): [True: 3.10k, False: 3.84k]
  |  Branch (1129:42): [True: 568, False: 2.53k]
  ------------------
 1130|    568|        h = _h3Rotate60cw(h);
 1131|       |
 1132|       |    // start with the "home" face and ijk+ coordinates for the base cell of c
 1133|  6.95k|    *fijk = baseCellData[baseCell].homeFijk;
 1134|  6.95k|    if (!_h3ToFaceIjkWithInitializedFijk(h, fijk))
  ------------------
  |  Branch (1134:9): [True: 865, False: 6.08k]
  ------------------
 1135|    865|        return E_SUCCESS;  // no overage is possible; h lies on this face
 1136|       |
 1137|       |    // if we're here we have the potential for an "overage"; i.e., it is
 1138|       |    // possible that c lies on an adjacent face
 1139|       |
 1140|  6.08k|    CoordIJK origIJK = fijk->coord;
 1141|       |
 1142|       |    // if we're in Class III, drop into the next finer Class II grid
 1143|  6.08k|    int res = H3_GET_RESOLUTION(h);
  ------------------
  |  |  129|  6.08k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  6.08k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  6.08k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  6.08k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
 1144|  6.08k|    if (isResolutionClassIII(res)) {
  ------------------
  |  Branch (1144:9): [True: 4.80k, False: 1.28k]
  ------------------
 1145|       |        // Class III
 1146|  4.80k|        _downAp7r(&fijk->coord);
 1147|  4.80k|        res++;
 1148|  4.80k|    }
 1149|       |
 1150|       |    // adjust for overage if needed
 1151|       |    // a pentagon base cell with a leading 4 digit requires special handling
 1152|  6.08k|    int pentLeading4 =
 1153|  6.08k|        (_isBaseCellPentagon(baseCell) && _h3LeadingNonZeroDigit(h) == 4);
  ------------------
  |  Branch (1153:10): [True: 3.10k, False: 2.98k]
  |  Branch (1153:43): [True: 844, False: 2.26k]
  ------------------
 1154|  6.08k|    if (_adjustOverageClassII(fijk, res, pentLeading4, 0) != NO_OVERAGE) {
  ------------------
  |  Branch (1154:9): [True: 3.37k, False: 2.71k]
  ------------------
 1155|       |        // if the base cell is a pentagon we have the potential for secondary
 1156|       |        // overages
 1157|  3.37k|        if (_isBaseCellPentagon(baseCell)) {
  ------------------
  |  Branch (1157:13): [True: 2.47k, False: 898]
  ------------------
 1158|  4.20k|            while (_adjustOverageClassII(fijk, res, 0, 0) != NO_OVERAGE)
  ------------------
  |  Branch (1158:20): [True: 1.73k, False: 2.47k]
  ------------------
 1159|  1.73k|                continue;
 1160|  2.47k|        }
 1161|       |
 1162|  3.37k|        if (res != H3_GET_RESOLUTION(h)) _upAp7r(&fijk->coord);
  ------------------
  |  |  129|  3.37k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  3.37k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  3.37k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  3.37k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (1162:13): [True: 2.69k, False: 678]
  ------------------
 1163|  3.37k|    } else if (res != H3_GET_RESOLUTION(h)) {
  ------------------
  |  |  129|  2.71k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  2.71k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  2.71k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  2.71k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  |  Branch (1163:16): [True: 2.11k, False: 607]
  ------------------
 1164|  2.11k|        fijk->coord = origIJK;
 1165|  2.11k|    }
 1166|  6.08k|    return E_SUCCESS;
 1167|  6.95k|}
isResolutionClassIII:
 1356|  87.8k|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|    234|static inline bool _hasAny7UptoRes(H3Index h, int res) {
  265|    234|    const uint64_t MHI = 0b100100100100100100100100100100100100100100100;
  266|    234|    const uint64_t MLO = MHI >> 2;
  267|       |
  268|    234|    int shift = 3 * (15 - res);
  269|    234|    h >>= shift;
  270|    234|    h <<= shift;
  271|    234|    h = (h & MHI & (~h - MLO));
  272|       |
  273|    234|    return h != 0;
  274|    234|}
h3Index.c:_hasAll7AfterRes:
  280|    199|static inline bool _hasAll7AfterRes(H3Index h, int res) {
  281|       |    // NOTE: res check is needed because we can't shift by 64
  282|    199|    if (res < 15) {
  ------------------
  |  Branch (282:9): [True: 105, False: 94]
  ------------------
  283|    105|        int shift = 19 + 3 * res;
  284|       |
  285|    105|        h = ~h;
  286|    105|        h <<= shift;
  287|    105|        h >>= shift;
  288|       |
  289|    105|        return h == 0;
  290|    105|    }
  291|     94|    return true;
  292|    199|}
h3Index.c:_hasDeletedSubsequence:
  327|    135|static inline bool _hasDeletedSubsequence(H3Index h, int base_cell) {
  328|    135|    if (isBaseCellPentagonArr[base_cell]) {
  ------------------
  |  Branch (328:9): [True: 79, False: 56]
  ------------------
  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: 1, False: 78]
  ------------------
  333|     78|        return _firstOneIndex(h) % 3 == 0;
  334|     79|    }
  335|     56|    return false;
  336|    135|}
h3Index.c:_firstOneIndex:
  300|     78|static inline int _firstOneIndex(H3Index h) {
  301|     78|#if defined(__GNUC__) || defined(__clang__)
  302|     78|    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|     78|}

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

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

vertexNumForDirection:
  130|  1.87k|int vertexNumForDirection(const H3Index origin, const Direction direction) {
  131|  1.87k|    int isPent = H3_EXPORT(isPentagon)(origin);
  ------------------
  |  |   36|  1.87k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  1.87k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  1.87k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  132|       |    // Check for invalid directions
  133|  1.87k|    if (direction == CENTER_DIGIT || direction >= INVALID_DIGIT ||
  ------------------
  |  Branch (133:9): [True: 0, False: 1.87k]
  |  Branch (133:38): [True: 21, False: 1.85k]
  ------------------
  134|  1.85k|        (isPent && direction == K_AXES_DIGIT))
  ------------------
  |  Branch (134:10): [True: 105, False: 1.74k]
  |  Branch (134:20): [True: 0, False: 105]
  ------------------
  135|     21|        return INVALID_VERTEX_NUM;
  ------------------
  |  |   36|     21|#define INVALID_VERTEX_NUM -1
  ------------------
  136|       |
  137|       |    // Determine the vertex rotations for this cell
  138|  1.85k|    int rotations;
  139|  1.85k|    H3Error err = vertexRotations(origin, &rotations);
  140|  1.85k|    if (err) {
  ------------------
  |  Branch (140:9): [True: 0, False: 1.85k]
  ------------------
  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|  1.85k|    if (isPent) {
  ------------------
  |  Branch (145:9): [True: 105, False: 1.74k]
  ------------------
  146|    105|        return (directionToVertexNumPent[direction] + NUM_PENT_VERTS -
  ------------------
  |  |   85|    105|#define NUM_PENT_VERTS 5
  ------------------
  147|    105|                rotations) %
  148|    105|               NUM_PENT_VERTS;
  ------------------
  |  |   85|    105|#define NUM_PENT_VERTS 5
  ------------------
  149|  1.74k|    } else {
  150|  1.74k|        return (directionToVertexNumHex[direction] + NUM_HEX_VERTS -
  ------------------
  |  |   83|  1.74k|#define NUM_HEX_VERTS 6
  ------------------
  151|  1.74k|                rotations) %
  152|  1.74k|               NUM_HEX_VERTS;
  ------------------
  |  |   83|  1.74k|#define NUM_HEX_VERTS 6
  ------------------
  153|  1.74k|    }
  154|  1.85k|}
directionForVertexNum:
  173|  4.58k|Direction directionForVertexNum(const H3Index origin, const int vertexNum) {
  174|  4.58k|    int isPent = H3_EXPORT(isPentagon)(origin);
  ------------------
  |  |   36|  4.58k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  4.58k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  4.58k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  175|       |    // Check for invalid vertexes
  176|  4.58k|    if (vertexNum < 0 ||
  ------------------
  |  Branch (176:9): [True: 0, False: 4.58k]
  ------------------
  177|  4.58k|        vertexNum > (isPent ? NUM_PENT_VERTS : NUM_HEX_VERTS) - 1)
  ------------------
  |  |   85|     78|#define NUM_PENT_VERTS 5
  ------------------
                      vertexNum > (isPent ? NUM_PENT_VERTS : NUM_HEX_VERTS) - 1)
  ------------------
  |  |   83|  4.50k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (177:9): [True: 0, False: 4.58k]
  |  Branch (177:22): [True: 78, False: 4.50k]
  ------------------
  178|      0|        return INVALID_DIGIT;
  179|       |
  180|       |    // Determine the vertex rotations for this cell
  181|  4.58k|    int rotations;
  182|  4.58k|    H3Error err = vertexRotations(origin, &rotations);
  183|  4.58k|    if (err) {
  ------------------
  |  Branch (183:9): [True: 5, False: 4.58k]
  ------------------
  184|      5|        return INVALID_DIGIT;
  185|      5|    }
  186|       |
  187|       |    // Find the appropriate direction, rotating CW if necessary
  188|  4.58k|    return isPent ? vertexNumToDirectionPent[(vertexNum + rotations) %
  ------------------
  |  Branch (188:12): [True: 78, False: 4.50k]
  ------------------
  189|     78|                                             NUM_PENT_VERTS]
  ------------------
  |  |   85|     78|#define NUM_PENT_VERTS 5
  ------------------
  190|  4.58k|                  : vertexNumToDirectionHex[(vertexNum + rotations) %
  191|  4.50k|                                            NUM_HEX_VERTS];
  ------------------
  |  |   83|  4.50k|#define NUM_HEX_VERTS 6
  ------------------
  192|  4.58k|}
cellToVertex:
  212|  3.23k|H3Error H3_EXPORT(cellToVertex)(H3Index cell, int vertexNum, H3Index *out) {
  213|  3.23k|    int cellIsPentagon = H3_EXPORT(isPentagon)(cell);
  ------------------
  |  |   36|  3.23k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  3.23k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  3.23k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  214|  3.23k|    int cellNumVerts = cellIsPentagon ? NUM_PENT_VERTS : NUM_HEX_VERTS;
  ------------------
  |  |   85|     63|#define NUM_PENT_VERTS 5
  ------------------
                  int cellNumVerts = cellIsPentagon ? NUM_PENT_VERTS : NUM_HEX_VERTS;
  ------------------
  |  |   83|  3.17k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (214:24): [True: 63, False: 3.17k]
  ------------------
  215|  3.23k|    int res = H3_GET_RESOLUTION(cell);
  ------------------
  |  |  129|  3.23k|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|  3.23k|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|  3.23k|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|  3.23k|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  216|       |
  217|       |    // Check for invalid vertexes
  218|  3.23k|    if (vertexNum < 0 || vertexNum > cellNumVerts - 1) return E_DOMAIN;
  ------------------
  |  Branch (218:9): [True: 148, False: 3.08k]
  |  Branch (218:26): [True: 276, False: 2.81k]
  ------------------
  219|       |
  220|       |    // Default the owner and vertex number to the input cell
  221|  2.81k|    H3Index owner = cell;
  222|  2.81k|    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|  2.81k|    if (res == 0 || H3_GET_INDEX_DIGIT(cell, res) != CENTER_DIGIT) {
  ------------------
  |  |  141|  2.51k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  2.51k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  2.51k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  2.51k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  2.51k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  |  Branch (229:9): [True: 295, False: 2.51k]
  |  Branch (229:21): [True: 2.23k, False: 284]
  ------------------
  230|       |        // Get the left neighbor of the vertex, with its rotations
  231|  2.52k|        Direction left = directionForVertexNum(cell, vertexNum);
  232|  2.52k|        if (left == INVALID_DIGIT) return E_FAILED;
  ------------------
  |  Branch (232:13): [True: 5, False: 2.52k]
  ------------------
  233|  2.52k|        int lRotations = 0;
  234|  2.52k|        H3Index leftNeighbor;
  235|  2.52k|        H3Error leftNeighborError =
  236|  2.52k|            h3NeighborRotations(cell, left, &lRotations, &leftNeighbor);
  237|  2.52k|        if (leftNeighborError) return leftNeighborError;
  ------------------
  |  Branch (237:13): [True: 110, False: 2.41k]
  ------------------
  238|       |        // Set to owner if lowest index
  239|  2.41k|        if (leftNeighbor < owner) owner = leftNeighbor;
  ------------------
  |  Branch (239:13): [True: 1.45k, False: 959]
  ------------------
  240|       |
  241|       |        // As above, skip the right neighbor if the left is known lowest
  242|  2.41k|        if (res == 0 || H3_GET_INDEX_DIGIT(leftNeighbor, res) != CENTER_DIGIT) {
  ------------------
  |  |  141|  2.12k|    ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   76|  2.12k|#define MAX_H3_RES 15
  |  |  ------------------
  |  |                   ((Direction)((((h3) >> ((MAX_H3_RES - (res)) * H3_PER_DIGIT_OFFSET)) & \
  |  |  ------------------
  |  |  |  |   47|  2.12k|#define H3_PER_DIGIT_OFFSET 3
  |  |  ------------------
  |  |  142|  2.12k|                  H3_DIGIT_MASK)))
  |  |  ------------------
  |  |  |  |   80|  2.12k|#define H3_DIGIT_MASK ((uint64_t)(7))
  |  |  ------------------
  ------------------
  |  Branch (242:13): [True: 292, False: 2.12k]
  |  Branch (242:25): [True: 1.76k, False: 358]
  ------------------
  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.05k|            Direction right = directionForVertexNum(
  246|  2.05k|                cell, (vertexNum - 1 + cellNumVerts) % cellNumVerts);
  247|       |            // This case should be unreachable; invalid verts fail earlier
  248|  2.05k|            if (NEVER(right == INVALID_DIGIT)) return E_FAILED;
  ------------------
  |  |  119|  2.05k|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 2.05k]
  |  |  |  Branch (119:19): [True: 0, False: 2.05k]
  |  |  ------------------
  ------------------
  |  Branch (248:17): [Folded, False: 0]
  |  Branch (248:17): [Folded, False: 0]
  ------------------
  249|  2.05k|            int rRotations = 0;
  250|  2.05k|            H3Index rightNeighbor;
  251|  2.05k|            H3Error rightNeighborError =
  252|  2.05k|                h3NeighborRotations(cell, right, &rRotations, &rightNeighbor);
  253|  2.05k|            if (rightNeighborError) return rightNeighborError;
  ------------------
  |  Branch (253:17): [True: 23, False: 2.03k]
  ------------------
  254|       |            // Set to owner if lowest index
  255|  2.03k|            if (rightNeighbor < owner) {
  ------------------
  |  Branch (255:17): [True: 927, False: 1.10k]
  ------------------
  256|    927|                owner = rightNeighbor;
  257|    927|                Direction dir =
  258|    927|                    H3_EXPORT(isPentagon)(owner)
  ------------------
  |  |   36|    927|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    927|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    927|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (258:21): [True: 66, False: 861]
  ------------------
  259|    927|                        ? directionForNeighbor(owner, cell)
  260|    927|                        : DIRECTIONS[(revNeighborDirectionsHex[right] +
  261|    861|                                      rRotations) %
  262|    861|                                     NUM_HEX_VERTS];
  ------------------
  |  |   83|    861|#define NUM_HEX_VERTS 6
  ------------------
  263|    927|                ownerVertexNum = vertexNumForDirection(owner, dir);
  264|    927|            }
  265|  2.03k|        }
  266|       |
  267|       |        // Determine the vertex number for the left neighbor
  268|  2.39k|        if (owner == leftNeighbor) {
  ------------------
  |  Branch (268:13): [True: 947, False: 1.44k]
  ------------------
  269|    947|            int ownerIsPentagon = H3_EXPORT(isPentagon)(owner);
  ------------------
  |  |   36|    947|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    947|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    947|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  270|    947|            Direction dir =
  271|    947|                ownerIsPentagon
  ------------------
  |  Branch (271:17): [True: 60, False: 887]
  ------------------
  272|    947|                    ? directionForNeighbor(owner, cell)
  273|    947|                    : DIRECTIONS[(revNeighborDirectionsHex[left] + lRotations) %
  274|    887|                                 NUM_HEX_VERTS];
  ------------------
  |  |   83|    887|#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|    947|            ownerVertexNum = vertexNumForDirection(owner, dir) + 1;
  279|    947|            if (ownerVertexNum == NUM_HEX_VERTS ||
  ------------------
  |  |   83|  1.89k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (279:17): [True: 166, False: 781]
  ------------------
  280|    781|                (ownerIsPentagon && ownerVertexNum == NUM_PENT_VERTS)) {
  ------------------
  |  |   85|     60|#define NUM_PENT_VERTS 5
  ------------------
  |  Branch (280:18): [True: 60, False: 721]
  |  Branch (280:37): [True: 6, False: 54]
  ------------------
  281|    172|                ownerVertexNum = 0;
  282|    172|            }
  283|    947|        }
  284|  2.39k|    }
  285|       |
  286|       |    // Create the vertex index
  287|  2.67k|    H3Index vertex = owner;
  288|  2.67k|    H3_SET_MODE(vertex, H3_VERTEX_MODE);
  ------------------
  |  |  113|  2.67k|    (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   59|  2.67k|#define H3_MODE_MASK_NEGATIVE (~H3_MODE_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   56|  2.67k|#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   35|  2.67k|#define H3_MODE_OFFSET 59
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   35|  2.67k|#define H3_MODE_OFFSET 59
  |  |  ------------------
  ------------------
  289|  2.67k|    H3_SET_RESERVED_BITS(vertex, ownerVertexNum);
  ------------------
  |  |  149|  2.67k|    (h3) = (((h3)&H3_RESERVED_MASK_NEGATIVE) | \
  |  |  ------------------
  |  |  |  |   77|  2.67k|#define H3_RESERVED_MASK_NEGATIVE (~H3_RESERVED_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   74|  2.67k|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   44|  2.67k|#define H3_RESERVED_OFFSET 56
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  150|  2.67k|            (((uint64_t)(v)) << H3_RESERVED_OFFSET))
  |  |  ------------------
  |  |  |  |   44|  2.67k|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  290|  2.67k|    *out = vertex;
  291|       |
  292|  2.67k|    return E_SUCCESS;
  293|  2.81k|}
cellToVertexes:
  300|    527|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|    527|    bool isPent = H3_EXPORT(isPentagon)(cell);
  ------------------
  |  |   36|    527|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    527|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    527|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  304|  2.99k|    for (int i = 0; i < NUM_HEX_VERTS; i++) {
  ------------------
  |  |   83|  2.99k|#define NUM_HEX_VERTS 6
  ------------------
  |  Branch (304:21): [True: 2.58k, False: 402]
  ------------------
  305|  2.58k|        if (i == 5 && isPent) {
  ------------------
  |  Branch (305:13): [True: 402, False: 2.18k]
  |  Branch (305:23): [True: 10, False: 392]
  ------------------
  306|     10|            vertexes[i] = H3_NULL;
  ------------------
  |  |   76|     10|#define H3_NULL 0
  ------------------
  307|  2.57k|        } else {
  308|  2.57k|            H3Error cellError = H3_EXPORT(cellToVertex)(cell, i, &vertexes[i]);
  ------------------
  |  |   36|  2.57k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  2.57k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  2.57k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  309|  2.57k|            if (cellError) {
  ------------------
  |  Branch (309:17): [True: 125, False: 2.45k]
  ------------------
  310|    125|                return cellError;
  311|    125|            }
  312|  2.57k|        }
  313|  2.58k|    }
  314|    402|    return E_SUCCESS;
  315|    527|}
vertexToLatLng:
  322|    527|H3Error H3_EXPORT(vertexToLatLng)(H3Index vertex, LatLng *coord) {
  323|       |    // Get the vertex number and owner from the vertex
  324|    527|    int vertexNum = H3_GET_RESERVED_BITS(vertex);
  ------------------
  |  |  156|    527|    ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET)))
  |  |  ------------------
  |  |  |  |   74|    527|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|    527|#define H3_RESERVED_OFFSET 56
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   ((int)((((h3)&H3_RESERVED_MASK) >> H3_RESERVED_OFFSET)))
  |  |  ------------------
  |  |  |  |   44|    527|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  325|    527|    H3Index owner = vertex;
  326|    527|    H3_SET_MODE(owner, H3_CELL_MODE);
  ------------------
  |  |  113|    527|    (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   59|    527|#define H3_MODE_MASK_NEGATIVE (~H3_MODE_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   56|    527|#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   35|    527|#define H3_MODE_OFFSET 59
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |                   (h3) = (((h3)&H3_MODE_MASK_NEGATIVE) | (((uint64_t)(v)) << H3_MODE_OFFSET))
  |  |  ------------------
  |  |  |  |   35|    527|#define H3_MODE_OFFSET 59
  |  |  ------------------
  ------------------
  327|    527|    H3_SET_RESERVED_BITS(owner, 0);
  ------------------
  |  |  149|    527|    (h3) = (((h3)&H3_RESERVED_MASK_NEGATIVE) | \
  |  |  ------------------
  |  |  |  |   77|    527|#define H3_RESERVED_MASK_NEGATIVE (~H3_RESERVED_MASK)
  |  |  |  |  ------------------
  |  |  |  |  |  |   74|    527|#define H3_RESERVED_MASK ((uint64_t)(7) << H3_RESERVED_OFFSET)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   44|    527|#define H3_RESERVED_OFFSET 56
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  150|    527|            (((uint64_t)(v)) << H3_RESERVED_OFFSET))
  |  |  ------------------
  |  |  |  |   44|    527|#define H3_RESERVED_OFFSET 56
  |  |  ------------------
  ------------------
  328|       |
  329|       |    // Get the single vertex from the boundary
  330|    527|    CellBoundary gb;
  331|    527|    FaceIJK fijk;
  332|    527|    H3Error fijkError = _h3ToFaceIjk(owner, &fijk);
  333|    527|    if (fijkError) {
  ------------------
  |  Branch (333:9): [True: 6, False: 521]
  ------------------
  334|      6|        return fijkError;
  335|      6|    }
  336|    521|    int res = H3_GET_RESOLUTION(owner);
  ------------------
  |  |  129|    521|#define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   68|    521|#define H3_RES_MASK (UINT64_C(15) << H3_RES_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   41|    521|#define H3_RES_OFFSET 52
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_RESOLUTION(h3) ((int)((((h3)&H3_RES_MASK) >> H3_RES_OFFSET)))
  |  |  ------------------
  |  |  |  |   41|    521|#define H3_RES_OFFSET 52
  |  |  ------------------
  ------------------
  337|       |
  338|    521|    if (H3_EXPORT(isPentagon)(owner)) {
  ------------------
  |  |   36|    521|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    521|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    521|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (338:9): [True: 10, False: 511]
  ------------------
  339|     10|        _faceIjkPentToCellBoundary(&fijk, res, vertexNum, 1, &gb);
  340|    511|    } else {
  341|    511|        _faceIjkToCellBoundary(&fijk, res, vertexNum, 1, &gb);
  342|    511|    }
  343|       |
  344|       |    // Copy from boundary to output coord
  345|    521|    *coord = gb.verts[0];
  346|    521|    return E_SUCCESS;
  347|    527|}
isValidVertex:
  354|    527|int H3_EXPORT(isValidVertex)(H3Index vertex) {
  355|    527|    if (H3_GET_MODE(vertex) != H3_VERTEX_MODE) {
  ------------------
  |  |  107|    527|#define H3_GET_MODE(h3) ((int)((((h3)&H3_MODE_MASK) >> H3_MODE_OFFSET)))
  |  |  ------------------
  |  |  |  |   56|    527|#define H3_MODE_MASK ((uint64_t)(15) << H3_MODE_OFFSET)
  |  |  |  |  ------------------
  |  |  |  |  |  |   35|    527|#define H3_MODE_OFFSET 59
  |  |  |  |  ------------------
  |  |  ------------------
  |  |               #define H3_GET_MODE(h3) ((int)((((h3)&H3_MODE_MASK) >> H3_MODE_OFFSET)))
  |  |  ------------------
  |  |  |  |   35|    527|#define H3_MODE_OFFSET 59
  |  |  ------------------
  ------------------
                  if (H3_GET_MODE(vertex) != H3_VERTEX_MODE) {
  ------------------
  |  |   93|    527|#define H3_VERTEX_MODE 4
  ------------------
  |  Branch (355:9): [True: 286, False: 241]
  ------------------
  356|    286|        return 0;
  357|    286|    }
  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: 110, False: 131]
  ------------------
  365|    110|        return 0;
  366|    110|    }
  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|    131|    H3Index canonical;
  371|    131|    if (H3_EXPORT(cellToVertex)(owner, vertexNum, &canonical)) {
  ------------------
  |  |   36|    131|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|    131|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|    131|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (371:9): [True: 13, False: 118]
  ------------------
  372|     13|        return 0;
  373|     13|    }
  374|       |
  375|    118|    return vertex == canonical ? 1 : 0;
  ------------------
  |  Branch (375:12): [True: 10, False: 108]
  ------------------
  376|    131|}
vertex.c:vertexRotations:
   53|  6.43k|static H3Error vertexRotations(H3Index cell, int *out) {
   54|       |    // Get the face and other info for the origin
   55|  6.43k|    FaceIJK fijk;
   56|  6.43k|    H3Error err = _h3ToFaceIjk(cell, &fijk);
   57|  6.43k|    if (err) {
  ------------------
  |  Branch (57:9): [True: 5, False: 6.43k]
  ------------------
   58|      5|        return err;
   59|      5|    }
   60|  6.43k|    int baseCell = H3_EXPORT(getBaseCellNumber)(cell);
  ------------------
  |  |   36|  6.43k|#define H3_EXPORT(name) TJOIN(H3_PREFIX, name)
  |  |  ------------------
  |  |  |  |   33|  6.43k|#define TJOIN(a, b) XTJOIN(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|  6.43k|#define XTJOIN(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   61|  6.43k|    int cellLeadingDigit = _h3LeadingNonZeroDigit(cell);
   62|       |
   63|       |    // get the base cell face
   64|  6.43k|    FaceIJK baseFijk;
   65|  6.43k|    _baseCellToFaceIjk(baseCell, &baseFijk);
   66|       |
   67|  6.43k|    int ccwRot60 = _baseCellToCCWrot60(baseCell, fijk.face);
   68|       |
   69|  6.43k|    if (_isBaseCellPentagon(baseCell)) {
  ------------------
  |  Branch (69:9): [True: 2.86k, False: 3.56k]
  ------------------
   70|       |        // Find the appropriate direction-to-face mapping
   71|  2.86k|        PentagonDirectionFaces dirFaces;
   72|       |        // We never hit the end condition
   73|  2.86k|        int p = 0;
   74|       |        // Don't use a for loop here, for coverage reasons.
   75|  16.3k|        while (ALWAYS(p < NUM_PENTAGONS)) {
  ------------------
  |  |  118|  16.3k|#define ALWAYS(X) ((X) ? 1 : (assert(0), 0))
  |  |  ------------------
  |  |  |  Branch (118:19): [True: 16.3k, False: 0]
  |  |  |  Branch (118:20): [True: 16.3k, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (75:16): [Folded, False: 0]
  |  Branch (75:16): [Folded, False: 0]
  ------------------
   76|  16.3k|            if (pentagonDirectionFaces[p].baseCell == baseCell) {
  ------------------
  |  Branch (76:17): [True: 2.86k, False: 13.5k]
  ------------------
   77|  2.86k|                dirFaces = pentagonDirectionFaces[p];
   78|  2.86k|                break;
   79|  2.86k|            }
   80|  13.5k|            p++;
   81|  13.5k|        }
   82|  2.86k|        if (NEVER(p == NUM_PENTAGONS)) {
  ------------------
  |  |  119|  2.86k|#define NEVER(X) ((X) ? (assert(0), 1) : 0)
  |  |  ------------------
  |  |  |  Branch (119:18): [True: 0, False: 2.86k]
  |  |  |  Branch (119:19): [True: 0, False: 2.86k]
  |  |  ------------------
  ------------------
  |  Branch (82:13): [Folded, False: 0]
  |  Branch (82:13): [Folded, False: 0]
  ------------------
   83|      0|            return E_FAILED;
   84|      0|        }
   85|       |
   86|       |        // additional CCW rotation for polar neighbors or IK neighbors
   87|  2.86k|        if (fijk.face != baseFijk.face &&
  ------------------
  |  Branch (87:13): [True: 2.27k, False: 590]
  ------------------
   88|  2.27k|            (_isBaseCellPolarPentagon(baseCell) ||
  ------------------
  |  Branch (88:14): [True: 749, False: 1.52k]
  ------------------
   89|  1.52k|             fijk.face ==
  ------------------
  |  Branch (89:14): [True: 483, False: 1.04k]
  ------------------
   90|  1.52k|                 dirFaces.faces[IK_AXES_DIGIT - DIRECTION_INDEX_OFFSET])) {
  ------------------
  |  |   32|  1.52k|#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|  2.86k|        if (cellLeadingDigit == JK_AXES_DIGIT &&
  ------------------
  |  Branch (95:13): [True: 522, False: 2.34k]
  ------------------
   96|    522|            fijk.face ==
  ------------------
  |  Branch (96:13): [True: 210, False: 312]
  ------------------
   97|    522|                dirFaces.faces[IK_AXES_DIGIT - DIRECTION_INDEX_OFFSET]) {
  ------------------
  |  |   32|    522|#define DIRECTION_INDEX_OFFSET 2
  ------------------
   98|       |            // Crosses from JK to IK: Rotate CW
   99|    210|            ccwRot60 = (ccwRot60 + 5) % 6;
  100|  2.65k|        } else if (cellLeadingDigit == IK_AXES_DIGIT &&
  ------------------
  |  Branch (100:20): [True: 526, False: 2.13k]
  ------------------
  101|    526|                   fijk.face ==
  ------------------
  |  Branch (101:20): [True: 58, False: 468]
  ------------------
  102|    526|                       dirFaces.faces[JK_AXES_DIGIT - DIRECTION_INDEX_OFFSET]) {
  ------------------
  |  |   32|    526|#define DIRECTION_INDEX_OFFSET 2
  ------------------
  103|       |            // Crosses from IK to JK: Rotate CCW
  104|     58|            ccwRot60 = (ccwRot60 + 1) % 6;
  105|     58|        }
  106|  2.86k|    }
  107|  6.43k|    *out = ccwRot60;
  108|  6.43k|    return E_SUCCESS;
  109|  6.43k|}

