Coverage Report

Created: 2026-05-24 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/h3/src/h3lib/include/coordijk.h
Line
Count
Source
1
/*
2
 * Copyright 2016-2018, 2020-2022, 2026 Uber Technologies, Inc.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *         http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
/** @file coordijk.h
17
 * @brief   Header-only implementation of CoordIJK functions including
18
 *          conversion from lat/lng.
19
 *
20
 * References two Vec2d cartesian coordinate systems:
21
 *
22
 *    1. gnomonic: face-centered polyhedral gnomonic projection space with
23
 *             traditional scaling and x-axes aligned with the face Class II
24
 *             i-axes.
25
 *
26
 *    2. hex2d: local face-centered coordinate system scaled a specific H3 grid
27
 *             resolution unit length and with x-axes aligned with the local
28
 *             i-axes
29
 */
30
31
#ifndef COORDIJK_H
32
#define COORDIJK_H
33
34
#include <math.h>
35
#include <stdlib.h>
36
37
#include "constants.h"
38
#include "h3Assert.h"
39
#include "h3api.h"
40
#include "mathExtensions.h"
41
#include "vec2d.h"
42
43
/** @struct CoordIJK
44
 * @brief IJK hexagon coordinates
45
 *
46
 * Each axis is spaced 120 degrees apart.
47
 */
48
typedef struct {
49
    int i;  ///< i component
50
    int j;  ///< j component
51
    int k;  ///< k component
52
} CoordIJK;
53
54
/** @brief CoordIJK unit vectors corresponding to the 7 H3 digits.
55
 */
56
static const CoordIJK UNIT_VECS[] = {
57
    {0, 0, 0},  // direction 0
58
    {0, 0, 1},  // direction 1
59
    {0, 1, 0},  // direction 2
60
    {0, 1, 1},  // direction 3
61
    {1, 0, 0},  // direction 4
62
    {1, 0, 1},  // direction 5
63
    {1, 1, 0}   // direction 6
64
};
65
66
/** @brief H3 digit representing ijk+ axes direction.
67
 * Values will be within the lowest 3 bits of an integer.
68
 */
69
typedef enum {
70
    /** H3 digit in center */
71
    CENTER_DIGIT = 0,
72
    /** H3 digit in k-axes direction */
73
    K_AXES_DIGIT = 1,
74
    /** H3 digit in j-axes direction */
75
    J_AXES_DIGIT = 2,
76
    /** H3 digit in j == k direction */
77
    JK_AXES_DIGIT = J_AXES_DIGIT | K_AXES_DIGIT, /* 3 */
78
    /** H3 digit in i-axes direction */
79
    I_AXES_DIGIT = 4,
80
    /** H3 digit in i == k direction */
81
    IK_AXES_DIGIT = I_AXES_DIGIT | K_AXES_DIGIT, /* 5 */
82
    /** H3 digit in i == j direction */
83
    IJ_AXES_DIGIT = I_AXES_DIGIT | J_AXES_DIGIT, /* 6 */
84
    /** H3 digit in the invalid direction */
85
    INVALID_DIGIT = 7,
86
    /** Valid digits will be less than this value. Same value as INVALID_DIGIT.
87
     */
88
    NUM_DIGITS = INVALID_DIGIT,
89
    /** Child digit which is skipped for pentagons */
90
    PENTAGON_SKIPPED_DIGIT = K_AXES_DIGIT /* 1 */
91
} Direction;
92
93
#define INT32_MAX_3 (INT32_MAX / 3)
94
95
/**
96
 * Sets an IJK coordinate to the specified component values.
97
 *
98
 * @param ijk The IJK coordinate to set.
99
 * @param i The desired i component value.
100
 * @param j The desired j component value.
101
 * @param k The desired k component value.
102
 */
103
0
static inline void _setIJK(CoordIJK *ijk, int i, int j, int k) {
104
0
    ijk->i = i;
105
0
    ijk->j = j;
106
0
    ijk->k = k;
107
0
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_setIJK
Unexecuted instantiation: h3Index.c:_setIJK
Unexecuted instantiation: vertex.c:_setIJK
Unexecuted instantiation: directedEdge.c:_setIJK
Unexecuted instantiation: iterators.c:_setIJK
Unexecuted instantiation: faceijk.c:_setIJK
Unexecuted instantiation: baseCells.c:_setIJK
Unexecuted instantiation: algos.c:_setIJK
Unexecuted instantiation: bbox.c:_setIJK
Unexecuted instantiation: cellsToMultiPoly.c:_setIJK
108
109
/**
110
 * Returns whether or not two ijk coordinates contain exactly the same
111
 * component values.
112
 *
113
 * @param c1 The first set of ijk coordinates.
114
 * @param c2 The second set of ijk coordinates.
115
 * @return 1 if the two addresses match, 0 if they do not.
116
 */
117
8.60k
static inline int _ijkMatches(const CoordIJK *c1, const CoordIJK *c2) {
118
8.60k
    return (c1->i == c2->i && c1->j == c2->j && c1->k == c2->k);
119
8.60k
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_ijkMatches
h3Index.c:_ijkMatches
Line
Count
Source
117
8.60k
static inline int _ijkMatches(const CoordIJK *c1, const CoordIJK *c2) {
118
8.60k
    return (c1->i == c2->i && c1->j == c2->j && c1->k == c2->k);
119
8.60k
}
Unexecuted instantiation: vertex.c:_ijkMatches
Unexecuted instantiation: directedEdge.c:_ijkMatches
Unexecuted instantiation: iterators.c:_ijkMatches
Unexecuted instantiation: faceijk.c:_ijkMatches
Unexecuted instantiation: baseCells.c:_ijkMatches
Unexecuted instantiation: algos.c:_ijkMatches
Unexecuted instantiation: bbox.c:_ijkMatches
Unexecuted instantiation: cellsToMultiPoly.c:_ijkMatches
120
121
/**
122
 * Add two ijk coordinates.
123
 *
124
 * @param h1 The first set of ijk coordinates.
125
 * @param h2 The second set of ijk coordinates.
126
 * @param sum The sum of the two sets of ijk coordinates.
127
 */
128
static inline void _ijkAdd(const CoordIJK *h1, const CoordIJK *h2,
129
4.48k
                           CoordIJK *sum) {
130
4.48k
    sum->i = h1->i + h2->i;
131
4.48k
    sum->j = h1->j + h2->j;
132
4.48k
    sum->k = h1->k + h2->k;
133
4.48k
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_ijkAdd
h3Index.c:_ijkAdd
Line
Count
Source
129
4.48k
                           CoordIJK *sum) {
130
4.48k
    sum->i = h1->i + h2->i;
131
4.48k
    sum->j = h1->j + h2->j;
132
4.48k
    sum->k = h1->k + h2->k;
133
4.48k
}
Unexecuted instantiation: vertex.c:_ijkAdd
Unexecuted instantiation: directedEdge.c:_ijkAdd
Unexecuted instantiation: iterators.c:_ijkAdd
Unexecuted instantiation: faceijk.c:_ijkAdd
Unexecuted instantiation: baseCells.c:_ijkAdd
Unexecuted instantiation: algos.c:_ijkAdd
Unexecuted instantiation: bbox.c:_ijkAdd
Unexecuted instantiation: cellsToMultiPoly.c:_ijkAdd
134
135
/**
136
 * Subtract two ijk coordinates.
137
 *
138
 * @param h1 The first set of ijk coordinates.
139
 * @param h2 The second set of ijk coordinates.
140
 * @param diff The difference of the two sets of ijk coordinates (h1 - h2).
141
 */
142
static inline void _ijkSub(const CoordIJK *h1, const CoordIJK *h2,
143
2.24k
                           CoordIJK *diff) {
144
2.24k
    diff->i = h1->i - h2->i;
145
2.24k
    diff->j = h1->j - h2->j;
146
2.24k
    diff->k = h1->k - h2->k;
147
2.24k
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_ijkSub
h3Index.c:_ijkSub
Line
Count
Source
143
2.24k
                           CoordIJK *diff) {
144
2.24k
    diff->i = h1->i - h2->i;
145
2.24k
    diff->j = h1->j - h2->j;
146
2.24k
    diff->k = h1->k - h2->k;
147
2.24k
}
Unexecuted instantiation: vertex.c:_ijkSub
Unexecuted instantiation: directedEdge.c:_ijkSub
Unexecuted instantiation: iterators.c:_ijkSub
Unexecuted instantiation: faceijk.c:_ijkSub
Unexecuted instantiation: baseCells.c:_ijkSub
Unexecuted instantiation: algos.c:_ijkSub
Unexecuted instantiation: bbox.c:_ijkSub
Unexecuted instantiation: cellsToMultiPoly.c:_ijkSub
148
149
/**
150
 * Uniformly scale ijk coordinates by a scalar. Works in place.
151
 *
152
 * @param c The ijk coordinates to scale.
153
 * @param factor The scaling factor.
154
 */
155
6.73k
static inline void _ijkScale(CoordIJK *c, int factor) {
156
6.73k
    c->i *= factor;
157
6.73k
    c->j *= factor;
158
6.73k
    c->k *= factor;
159
6.73k
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_ijkScale
h3Index.c:_ijkScale
Line
Count
Source
155
6.73k
static inline void _ijkScale(CoordIJK *c, int factor) {
156
6.73k
    c->i *= factor;
157
6.73k
    c->j *= factor;
158
6.73k
    c->k *= factor;
159
6.73k
}
Unexecuted instantiation: vertex.c:_ijkScale
Unexecuted instantiation: directedEdge.c:_ijkScale
Unexecuted instantiation: iterators.c:_ijkScale
Unexecuted instantiation: faceijk.c:_ijkScale
Unexecuted instantiation: baseCells.c:_ijkScale
Unexecuted instantiation: algos.c:_ijkScale
Unexecuted instantiation: bbox.c:_ijkScale
Unexecuted instantiation: cellsToMultiPoly.c:_ijkScale
160
161
/**
162
 * Returns true if _ijkNormalize with the given input could have a signed
163
 * integer overflow. Assumes k is set to 0.
164
 */
165
0
static inline bool _ijkNormalizeCouldOverflow(const CoordIJK *ijk) {
166
0
    // Check for the possibility of overflow
167
0
    int max, min;
168
0
    if (ijk->i > ijk->j) {
169
0
        max = ijk->i;
170
0
        min = ijk->j;
171
0
    } else {
172
0
        max = ijk->j;
173
0
        min = ijk->i;
174
0
    }
175
0
    if (min < 0) {
176
0
        // Only if the min is less than 0 will the resulting number be larger
177
0
        // than max. If min is positive, then max is also positive, and a
178
0
        // positive signed integer minus another positive signed integer will
179
0
        // not overflow.
180
0
        if (ADD_INT32S_OVERFLOWS(max, min)) {
181
0
            // max + min would overflow
182
0
            return true;
183
0
        }
184
0
        if (SUB_INT32S_OVERFLOWS(0, min)) {
185
0
            // 0 - INT32_MIN would overflow
186
0
            return true;
187
0
        }
188
0
        if (SUB_INT32S_OVERFLOWS(max, min)) {
189
0
            // max - min would overflow
190
0
            return true;
191
0
        }
192
0
    }
193
0
    return false;
194
0
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: h3Index.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: vertex.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: directedEdge.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: iterators.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: faceijk.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: baseCells.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: algos.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: bbox.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: cellsToMultiPoly.c:_ijkNormalizeCouldOverflow
195
196
/**
197
 * Normalizes ijk coordinates by setting the components to the smallest possible
198
 * values. Works in place.
199
 *
200
 * This function does not protect against signed integer overflow. The caller
201
 * must ensure that none of (i - j), (i - k), (j - i), (j - k), (k - i), (k -
202
 * j) will overflow. This function may be changed in the future to make that
203
 * check itself and return an error code.
204
 *
205
 * @param c The ijk coordinates to normalize.
206
 */
207
9.17k
static inline void _ijkNormalize(CoordIJK *c) {
208
    // remove any negative values
209
9.17k
    if (c->i < 0) {
210
1.26k
        c->j -= c->i;
211
1.26k
        c->k -= c->i;
212
1.26k
        c->i = 0;
213
1.26k
    }
214
215
9.17k
    if (c->j < 0) {
216
1.36k
        c->i -= c->j;
217
1.36k
        c->k -= c->j;
218
1.36k
        c->j = 0;
219
1.36k
    }
220
221
9.17k
    if (c->k < 0) {
222
248
        c->i -= c->k;
223
248
        c->j -= c->k;
224
248
        c->k = 0;
225
248
    }
226
227
    // remove the min value if needed
228
9.17k
    int min = c->i;
229
9.17k
    if (c->j < min) min = c->j;
230
9.17k
    if (c->k < min) min = c->k;
231
9.17k
    if (min > 0) {
232
1.94k
        c->i -= min;
233
1.94k
        c->j -= min;
234
1.94k
        c->k -= min;
235
1.94k
    }
236
9.17k
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_ijkNormalize
h3Index.c:_ijkNormalize
Line
Count
Source
207
8.97k
static inline void _ijkNormalize(CoordIJK *c) {
208
    // remove any negative values
209
8.97k
    if (c->i < 0) {
210
1.19k
        c->j -= c->i;
211
1.19k
        c->k -= c->i;
212
1.19k
        c->i = 0;
213
1.19k
    }
214
215
8.97k
    if (c->j < 0) {
216
1.26k
        c->i -= c->j;
217
1.26k
        c->k -= c->j;
218
1.26k
        c->j = 0;
219
1.26k
    }
220
221
8.97k
    if (c->k < 0) {
222
248
        c->i -= c->k;
223
248
        c->j -= c->k;
224
248
        c->k = 0;
225
248
    }
226
227
    // remove the min value if needed
228
8.97k
    int min = c->i;
229
8.97k
    if (c->j < min) min = c->j;
230
8.97k
    if (c->k < min) min = c->k;
231
8.97k
    if (min > 0) {
232
1.94k
        c->i -= min;
233
1.94k
        c->j -= min;
234
1.94k
        c->k -= min;
235
1.94k
    }
236
8.97k
}
Unexecuted instantiation: vertex.c:_ijkNormalize
Unexecuted instantiation: directedEdge.c:_ijkNormalize
Unexecuted instantiation: iterators.c:_ijkNormalize
faceijk.c:_ijkNormalize
Line
Count
Source
207
197
static inline void _ijkNormalize(CoordIJK *c) {
208
    // remove any negative values
209
197
    if (c->i < 0) {
210
70
        c->j -= c->i;
211
70
        c->k -= c->i;
212
70
        c->i = 0;
213
70
    }
214
215
197
    if (c->j < 0) {
216
99
        c->i -= c->j;
217
99
        c->k -= c->j;
218
99
        c->j = 0;
219
99
    }
220
221
197
    if (c->k < 0) {
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
197
    int min = c->i;
229
197
    if (c->j < min) min = c->j;
230
197
    if (c->k < min) min = c->k;
231
197
    if (min > 0) {
232
0
        c->i -= min;
233
0
        c->j -= min;
234
0
        c->k -= min;
235
0
    }
236
197
}
Unexecuted instantiation: baseCells.c:_ijkNormalize
Unexecuted instantiation: algos.c:_ijkNormalize
Unexecuted instantiation: bbox.c:_ijkNormalize
Unexecuted instantiation: cellsToMultiPoly.c:_ijkNormalize
237
238
/**
239
 * Find the center point in 2D cartesian coordinates of a hex.
240
 *
241
 * @param h The ijk coordinates of the hex.
242
 * @param v The 2D cartesian coordinates of the hex center point.
243
 */
244
0
static inline void _ijkToHex2d(const CoordIJK *h, Vec2d *v) {
245
0
    int i = h->i - h->k;
246
0
    int j = h->j - h->k;
247
248
0
    v->x = i - 0.5 * j;
249
0
    v->y = j * M_SQRT3_2;
250
0
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_ijkToHex2d
Unexecuted instantiation: h3Index.c:_ijkToHex2d
Unexecuted instantiation: vertex.c:_ijkToHex2d
Unexecuted instantiation: directedEdge.c:_ijkToHex2d
Unexecuted instantiation: iterators.c:_ijkToHex2d
Unexecuted instantiation: faceijk.c:_ijkToHex2d
Unexecuted instantiation: baseCells.c:_ijkToHex2d
Unexecuted instantiation: algos.c:_ijkToHex2d
Unexecuted instantiation: bbox.c:_ijkToHex2d
Unexecuted instantiation: cellsToMultiPoly.c:_ijkToHex2d
251
252
/**
253
 * Determine the containing hex in ijk+ coordinates for a 2D cartesian
254
 * coordinate vector (from DGGRID).
255
 *
256
 * @param v The 2D cartesian coordinate vector.
257
 * @param h The ijk+ coordinates of the containing hex.
258
 */
259
197
static inline void _hex2dToCoordIJK(const Vec2d *v, CoordIJK *h) {
260
197
    double a1, a2;
261
197
    double x1, x2;
262
197
    int m1, m2;
263
197
    double r1, r2;
264
265
    // quantize into the ij system and then normalize
266
197
    h->k = 0;
267
268
197
    a1 = fabsl(v->x);
269
197
    a2 = fabsl(v->y);
270
271
    // first do a reverse conversion
272
197
    x2 = a2 * M_RSIN60;
273
197
    x1 = a1 + x2 / 2.0;
274
275
    // check if we have the center of a hex
276
197
    m1 = (int)x1;
277
197
    m2 = (int)x2;
278
279
    // otherwise round correctly
280
197
    r1 = x1 - m1;
281
197
    r2 = x2 - m2;
282
283
197
    if (r1 < 0.5) {
284
94
        if (r1 < 1.0 / 3.0) {
285
58
            if (r2 < (1.0 + r1) / 2.0) {
286
41
                h->i = m1;
287
41
                h->j = m2;
288
41
            } else {
289
17
                h->i = m1;
290
17
                h->j = m2 + 1;
291
17
            }
292
58
        } else {
293
36
            if (r2 < (1.0 - r1)) {
294
25
                h->j = m2;
295
25
            } else {
296
11
                h->j = m2 + 1;
297
11
            }
298
299
36
            if ((1.0 - r1) <= r2 && r2 < (2.0 * r1)) {
300
7
                h->i = m1 + 1;
301
29
            } else {
302
29
                h->i = m1;
303
29
            }
304
36
        }
305
103
    } else {
306
103
        if (r1 < 2.0 / 3.0) {
307
39
            if (r2 < (1.0 - r1)) {
308
13
                h->j = m2;
309
26
            } else {
310
26
                h->j = m2 + 1;
311
26
            }
312
313
39
            if ((2.0 * r1 - 1.0) < r2 && r2 < (1.0 - r1)) {
314
8
                h->i = m1;
315
31
            } else {
316
31
                h->i = m1 + 1;
317
31
            }
318
64
        } else {
319
64
            if (r2 < (r1 / 2.0)) {
320
29
                h->i = m1 + 1;
321
29
                h->j = m2;
322
35
            } else {
323
35
                h->i = m1 + 1;
324
35
                h->j = m2 + 1;
325
35
            }
326
64
        }
327
103
    }
328
329
    // now fold across the axes if necessary
330
331
197
    if (v->x < 0.0) {
332
86
        if ((h->j % 2) == 0)  // even
333
38
        {
334
38
            long long int axisi = h->j / 2;
335
38
            long long int diff = h->i - axisi;
336
38
            h->i = (int)(h->i - 2.0 * diff);
337
48
        } else {
338
48
            long long int axisi = (h->j + 1) / 2;
339
48
            long long int diff = h->i - axisi;
340
48
            h->i = (int)(h->i - (2.0 * diff + 1));
341
48
        }
342
86
    }
343
344
197
    if (v->y < 0.0) {
345
135
        h->i = h->i - (2 * h->j + 1) / 2;
346
135
        h->j = -1 * h->j;
347
135
    }
348
349
197
    _ijkNormalize(h);
350
197
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_hex2dToCoordIJK
Unexecuted instantiation: h3Index.c:_hex2dToCoordIJK
Unexecuted instantiation: vertex.c:_hex2dToCoordIJK
Unexecuted instantiation: directedEdge.c:_hex2dToCoordIJK
Unexecuted instantiation: iterators.c:_hex2dToCoordIJK
faceijk.c:_hex2dToCoordIJK
Line
Count
Source
259
197
static inline void _hex2dToCoordIJK(const Vec2d *v, CoordIJK *h) {
260
197
    double a1, a2;
261
197
    double x1, x2;
262
197
    int m1, m2;
263
197
    double r1, r2;
264
265
    // quantize into the ij system and then normalize
266
197
    h->k = 0;
267
268
197
    a1 = fabsl(v->x);
269
197
    a2 = fabsl(v->y);
270
271
    // first do a reverse conversion
272
197
    x2 = a2 * M_RSIN60;
273
197
    x1 = a1 + x2 / 2.0;
274
275
    // check if we have the center of a hex
276
197
    m1 = (int)x1;
277
197
    m2 = (int)x2;
278
279
    // otherwise round correctly
280
197
    r1 = x1 - m1;
281
197
    r2 = x2 - m2;
282
283
197
    if (r1 < 0.5) {
284
94
        if (r1 < 1.0 / 3.0) {
285
58
            if (r2 < (1.0 + r1) / 2.0) {
286
41
                h->i = m1;
287
41
                h->j = m2;
288
41
            } else {
289
17
                h->i = m1;
290
17
                h->j = m2 + 1;
291
17
            }
292
58
        } else {
293
36
            if (r2 < (1.0 - r1)) {
294
25
                h->j = m2;
295
25
            } else {
296
11
                h->j = m2 + 1;
297
11
            }
298
299
36
            if ((1.0 - r1) <= r2 && r2 < (2.0 * r1)) {
300
7
                h->i = m1 + 1;
301
29
            } else {
302
29
                h->i = m1;
303
29
            }
304
36
        }
305
103
    } else {
306
103
        if (r1 < 2.0 / 3.0) {
307
39
            if (r2 < (1.0 - r1)) {
308
13
                h->j = m2;
309
26
            } else {
310
26
                h->j = m2 + 1;
311
26
            }
312
313
39
            if ((2.0 * r1 - 1.0) < r2 && r2 < (1.0 - r1)) {
314
8
                h->i = m1;
315
31
            } else {
316
31
                h->i = m1 + 1;
317
31
            }
318
64
        } else {
319
64
            if (r2 < (r1 / 2.0)) {
320
29
                h->i = m1 + 1;
321
29
                h->j = m2;
322
35
            } else {
323
35
                h->i = m1 + 1;
324
35
                h->j = m2 + 1;
325
35
            }
326
64
        }
327
103
    }
328
329
    // now fold across the axes if necessary
330
331
197
    if (v->x < 0.0) {
332
86
        if ((h->j % 2) == 0)  // even
333
38
        {
334
38
            long long int axisi = h->j / 2;
335
38
            long long int diff = h->i - axisi;
336
38
            h->i = (int)(h->i - 2.0 * diff);
337
48
        } else {
338
48
            long long int axisi = (h->j + 1) / 2;
339
48
            long long int diff = h->i - axisi;
340
48
            h->i = (int)(h->i - (2.0 * diff + 1));
341
48
        }
342
86
    }
343
344
197
    if (v->y < 0.0) {
345
135
        h->i = h->i - (2 * h->j + 1) / 2;
346
135
        h->j = -1 * h->j;
347
135
    }
348
349
197
    _ijkNormalize(h);
350
197
}
Unexecuted instantiation: baseCells.c:_hex2dToCoordIJK
Unexecuted instantiation: algos.c:_hex2dToCoordIJK
Unexecuted instantiation: bbox.c:_hex2dToCoordIJK
Unexecuted instantiation: cellsToMultiPoly.c:_hex2dToCoordIJK
351
352
/**
353
 * Determines the H3 digit corresponding to a unit vector or the zero vector
354
 * in ijk coordinates.
355
 *
356
 * @param ijk The ijk coordinates; must be a unit vector or zero vector.
357
 * @return The H3 digit (0-6) corresponding to the ijk unit vector, zero
358
 * vector, or INVALID_DIGIT (7) on failure.
359
 */
360
2.24k
static inline Direction _unitIjkToDigit(const CoordIJK *ijk) {
361
2.24k
    CoordIJK c = *ijk;
362
2.24k
    _ijkNormalize(&c);
363
364
2.24k
    Direction digit = INVALID_DIGIT;
365
8.60k
    for (Direction i = CENTER_DIGIT; i < NUM_DIGITS; i++) {
366
8.60k
        if (_ijkMatches(&c, &UNIT_VECS[i])) {
367
2.24k
            digit = i;
368
2.24k
            break;
369
2.24k
        }
370
8.60k
    }
371
372
2.24k
    return digit;
373
2.24k
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_unitIjkToDigit
h3Index.c:_unitIjkToDigit
Line
Count
Source
360
2.24k
static inline Direction _unitIjkToDigit(const CoordIJK *ijk) {
361
2.24k
    CoordIJK c = *ijk;
362
2.24k
    _ijkNormalize(&c);
363
364
2.24k
    Direction digit = INVALID_DIGIT;
365
8.60k
    for (Direction i = CENTER_DIGIT; i < NUM_DIGITS; i++) {
366
8.60k
        if (_ijkMatches(&c, &UNIT_VECS[i])) {
367
2.24k
            digit = i;
368
2.24k
            break;
369
2.24k
        }
370
8.60k
    }
371
372
2.24k
    return digit;
373
2.24k
}
Unexecuted instantiation: vertex.c:_unitIjkToDigit
Unexecuted instantiation: directedEdge.c:_unitIjkToDigit
Unexecuted instantiation: iterators.c:_unitIjkToDigit
Unexecuted instantiation: faceijk.c:_unitIjkToDigit
Unexecuted instantiation: baseCells.c:_unitIjkToDigit
Unexecuted instantiation: algos.c:_unitIjkToDigit
Unexecuted instantiation: bbox.c:_unitIjkToDigit
Unexecuted instantiation: cellsToMultiPoly.c:_unitIjkToDigit
374
375
/**
376
 * Returns non-zero if _upAp7 with the given input could have a signed integer
377
 * overflow.
378
 *
379
 * Assumes ijk is IJK+ coordinates (no negative numbers).
380
 */
381
0
static inline H3Error _upAp7Checked(CoordIJK *ijk) {
382
0
    // Doesn't need to be checked because i, j, and k must all be non-negative
383
0
    int i = ijk->i - ijk->k;
384
0
    int j = ijk->j - ijk->k;
385
0
386
0
    // <0 is checked because the input must all be non-negative, but some
387
0
    // negative inputs are used in unit tests to exercise the below.
388
0
    if (i >= INT32_MAX_3 || j >= INT32_MAX_3 || i < 0 || j < 0) {
389
0
        if (ADD_INT32S_OVERFLOWS(i, i)) {
390
0
            return E_FAILED;
391
0
        }
392
0
        int i2 = i + i;
393
0
        if (ADD_INT32S_OVERFLOWS(i2, i)) {
394
0
            return E_FAILED;
395
0
        }
396
0
        int i3 = i2 + i;
397
0
        if (ADD_INT32S_OVERFLOWS(j, j)) {
398
0
            return E_FAILED;
399
0
        }
400
0
        int j2 = j + j;
401
0
402
0
        if (SUB_INT32S_OVERFLOWS(i3, j)) {
403
0
            return E_FAILED;
404
0
        }
405
0
        if (ADD_INT32S_OVERFLOWS(i, j2)) {
406
0
            return E_FAILED;
407
0
        }
408
0
    }
409
0
410
0
    ijk->i = (int)lround(((i * 3) - j) * M_ONESEVENTH);
411
0
    ijk->j = (int)lround((i + (j * 2)) * M_ONESEVENTH);
412
0
    ijk->k = 0;
413
0
414
0
    // Expected not to be reachable, because max + min or max - min would need
415
0
    // to overflow.
416
0
    if (NEVER(_ijkNormalizeCouldOverflow(ijk))) {
417
0
        return E_FAILED;
418
0
    }
419
0
    _ijkNormalize(ijk);
420
0
    return E_SUCCESS;
421
0
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_upAp7Checked
Unexecuted instantiation: h3Index.c:_upAp7Checked
Unexecuted instantiation: vertex.c:_upAp7Checked
Unexecuted instantiation: directedEdge.c:_upAp7Checked
Unexecuted instantiation: iterators.c:_upAp7Checked
Unexecuted instantiation: faceijk.c:_upAp7Checked
Unexecuted instantiation: baseCells.c:_upAp7Checked
Unexecuted instantiation: algos.c:_upAp7Checked
Unexecuted instantiation: bbox.c:_upAp7Checked
Unexecuted instantiation: cellsToMultiPoly.c:_upAp7Checked
422
423
/**
424
 * Returns non-zero if _upAp7r with the given input could have a signed integer
425
 * overflow.
426
 *
427
 * Assumes ijk is IJK+ coordinates (no negative numbers).
428
 */
429
0
static inline H3Error _upAp7rChecked(CoordIJK *ijk) {
430
0
    // Doesn't need to be checked because i, j, and k must all be non-negative
431
0
    int i = ijk->i - ijk->k;
432
0
    int j = ijk->j - ijk->k;
433
0
434
0
    // <0 is checked because the input must all be non-negative, but some
435
0
    // negative inputs are used in unit tests to exercise the below.
436
0
    if (i >= INT32_MAX_3 || j >= INT32_MAX_3 || i < 0 || j < 0) {
437
0
        if (ADD_INT32S_OVERFLOWS(i, i)) {
438
0
            return E_FAILED;
439
0
        }
440
0
        int i2 = i + i;
441
0
        if (ADD_INT32S_OVERFLOWS(j, j)) {
442
0
            return E_FAILED;
443
0
        }
444
0
        int j2 = j + j;
445
0
        if (ADD_INT32S_OVERFLOWS(j2, j)) {
446
0
            return E_FAILED;
447
0
        }
448
0
        int j3 = j2 + j;
449
0
450
0
        if (ADD_INT32S_OVERFLOWS(i2, j)) {
451
0
            return E_FAILED;
452
0
        }
453
0
        if (SUB_INT32S_OVERFLOWS(j3, i)) {
454
0
            return E_FAILED;
455
0
        }
456
0
    }
457
0
458
0
    ijk->i = (int)lround(((i * 2) + j) * M_ONESEVENTH);
459
0
    ijk->j = (int)lround(((j * 3) - i) * M_ONESEVENTH);
460
0
    ijk->k = 0;
461
0
462
0
    // Expected not to be reachable, because max + min or max - min would need
463
0
    // to overflow.
464
0
    if (NEVER(_ijkNormalizeCouldOverflow(ijk))) {
465
0
        return E_FAILED;
466
0
    }
467
0
    _ijkNormalize(ijk);
468
0
    return E_SUCCESS;
469
0
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_upAp7rChecked
Unexecuted instantiation: h3Index.c:_upAp7rChecked
Unexecuted instantiation: vertex.c:_upAp7rChecked
Unexecuted instantiation: directedEdge.c:_upAp7rChecked
Unexecuted instantiation: iterators.c:_upAp7rChecked
Unexecuted instantiation: faceijk.c:_upAp7rChecked
Unexecuted instantiation: baseCells.c:_upAp7rChecked
Unexecuted instantiation: algos.c:_upAp7rChecked
Unexecuted instantiation: bbox.c:_upAp7rChecked
Unexecuted instantiation: cellsToMultiPoly.c:_upAp7rChecked
470
471
/**
472
 * Find the normalized ijk coordinates of the indexing parent of a cell in a
473
 * counter-clockwise aperture 7 grid. Works in place.
474
 *
475
 * @param ijk The ijk coordinates.
476
 */
477
1.20k
static inline void _upAp7(CoordIJK *ijk) {
478
    // convert to CoordIJ
479
1.20k
    int i = ijk->i - ijk->k;
480
1.20k
    int j = ijk->j - ijk->k;
481
482
1.20k
    ijk->i = (int)lround((3 * i - j) * M_ONESEVENTH);
483
1.20k
    ijk->j = (int)lround((i + 2 * j) * M_ONESEVENTH);
484
1.20k
    ijk->k = 0;
485
1.20k
    _ijkNormalize(ijk);
486
1.20k
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_upAp7
h3Index.c:_upAp7
Line
Count
Source
477
1.20k
static inline void _upAp7(CoordIJK *ijk) {
478
    // convert to CoordIJ
479
1.20k
    int i = ijk->i - ijk->k;
480
1.20k
    int j = ijk->j - ijk->k;
481
482
1.20k
    ijk->i = (int)lround((3 * i - j) * M_ONESEVENTH);
483
1.20k
    ijk->j = (int)lround((i + 2 * j) * M_ONESEVENTH);
484
1.20k
    ijk->k = 0;
485
1.20k
    _ijkNormalize(ijk);
486
1.20k
}
Unexecuted instantiation: vertex.c:_upAp7
Unexecuted instantiation: directedEdge.c:_upAp7
Unexecuted instantiation: iterators.c:_upAp7
Unexecuted instantiation: faceijk.c:_upAp7
Unexecuted instantiation: baseCells.c:_upAp7
Unexecuted instantiation: algos.c:_upAp7
Unexecuted instantiation: bbox.c:_upAp7
Unexecuted instantiation: cellsToMultiPoly.c:_upAp7
487
488
/**
489
 * Find the normalized ijk coordinates of the indexing parent of a cell in a
490
 * clockwise aperture 7 grid. Works in place.
491
 *
492
 * @param ijk The ijk coordinates.
493
 */
494
1.04k
static inline void _upAp7r(CoordIJK *ijk) {
495
    // convert to CoordIJ
496
1.04k
    int i = ijk->i - ijk->k;
497
1.04k
    int j = ijk->j - ijk->k;
498
499
1.04k
    ijk->i = (int)lround((2 * i + j) * M_ONESEVENTH);
500
1.04k
    ijk->j = (int)lround((3 * j - i) * M_ONESEVENTH);
501
1.04k
    ijk->k = 0;
502
1.04k
    _ijkNormalize(ijk);
503
1.04k
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_upAp7r
h3Index.c:_upAp7r
Line
Count
Source
494
1.04k
static inline void _upAp7r(CoordIJK *ijk) {
495
    // convert to CoordIJ
496
1.04k
    int i = ijk->i - ijk->k;
497
1.04k
    int j = ijk->j - ijk->k;
498
499
1.04k
    ijk->i = (int)lround((2 * i + j) * M_ONESEVENTH);
500
1.04k
    ijk->j = (int)lround((3 * j - i) * M_ONESEVENTH);
501
1.04k
    ijk->k = 0;
502
1.04k
    _ijkNormalize(ijk);
503
1.04k
}
Unexecuted instantiation: vertex.c:_upAp7r
Unexecuted instantiation: directedEdge.c:_upAp7r
Unexecuted instantiation: iterators.c:_upAp7r
Unexecuted instantiation: faceijk.c:_upAp7r
Unexecuted instantiation: baseCells.c:_upAp7r
Unexecuted instantiation: algos.c:_upAp7r
Unexecuted instantiation: bbox.c:_upAp7r
Unexecuted instantiation: cellsToMultiPoly.c:_upAp7r
504
505
/**
506
 * Find the normalized ijk coordinates of the hex centered on the indicated
507
 * hex at the next finer aperture 7 counter-clockwise resolution. Works in
508
 * place.
509
 *
510
 * @param ijk The ijk coordinates.
511
 */
512
1.20k
static inline void _downAp7(CoordIJK *ijk) {
513
    // res r unit vectors in res r+1
514
1.20k
    CoordIJK iVec = {3, 0, 1};
515
1.20k
    CoordIJK jVec = {1, 3, 0};
516
1.20k
    CoordIJK kVec = {0, 1, 3};
517
518
1.20k
    _ijkScale(&iVec, ijk->i);
519
1.20k
    _ijkScale(&jVec, ijk->j);
520
1.20k
    _ijkScale(&kVec, ijk->k);
521
522
1.20k
    _ijkAdd(&iVec, &jVec, ijk);
523
1.20k
    _ijkAdd(ijk, &kVec, ijk);
524
525
1.20k
    _ijkNormalize(ijk);
526
1.20k
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_downAp7
h3Index.c:_downAp7
Line
Count
Source
512
1.20k
static inline void _downAp7(CoordIJK *ijk) {
513
    // res r unit vectors in res r+1
514
1.20k
    CoordIJK iVec = {3, 0, 1};
515
1.20k
    CoordIJK jVec = {1, 3, 0};
516
1.20k
    CoordIJK kVec = {0, 1, 3};
517
518
1.20k
    _ijkScale(&iVec, ijk->i);
519
1.20k
    _ijkScale(&jVec, ijk->j);
520
1.20k
    _ijkScale(&kVec, ijk->k);
521
522
1.20k
    _ijkAdd(&iVec, &jVec, ijk);
523
1.20k
    _ijkAdd(ijk, &kVec, ijk);
524
525
1.20k
    _ijkNormalize(ijk);
526
1.20k
}
Unexecuted instantiation: vertex.c:_downAp7
Unexecuted instantiation: directedEdge.c:_downAp7
Unexecuted instantiation: iterators.c:_downAp7
Unexecuted instantiation: faceijk.c:_downAp7
Unexecuted instantiation: baseCells.c:_downAp7
Unexecuted instantiation: algos.c:_downAp7
Unexecuted instantiation: bbox.c:_downAp7
Unexecuted instantiation: cellsToMultiPoly.c:_downAp7
527
528
/**
529
 * Find the normalized ijk coordinates of the hex centered on the indicated
530
 * hex at the next finer aperture 7 clockwise resolution. Works in place.
531
 *
532
 * @param ijk The ijk coordinates.
533
 */
534
1.04k
static inline void _downAp7r(CoordIJK *ijk) {
535
    // res r unit vectors in res r+1
536
1.04k
    CoordIJK iVec = {3, 1, 0};
537
1.04k
    CoordIJK jVec = {0, 3, 1};
538
1.04k
    CoordIJK kVec = {1, 0, 3};
539
540
1.04k
    _ijkScale(&iVec, ijk->i);
541
1.04k
    _ijkScale(&jVec, ijk->j);
542
1.04k
    _ijkScale(&kVec, ijk->k);
543
544
1.04k
    _ijkAdd(&iVec, &jVec, ijk);
545
1.04k
    _ijkAdd(ijk, &kVec, ijk);
546
547
1.04k
    _ijkNormalize(ijk);
548
1.04k
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_downAp7r
h3Index.c:_downAp7r
Line
Count
Source
534
1.04k
static inline void _downAp7r(CoordIJK *ijk) {
535
    // res r unit vectors in res r+1
536
1.04k
    CoordIJK iVec = {3, 1, 0};
537
1.04k
    CoordIJK jVec = {0, 3, 1};
538
1.04k
    CoordIJK kVec = {1, 0, 3};
539
540
1.04k
    _ijkScale(&iVec, ijk->i);
541
1.04k
    _ijkScale(&jVec, ijk->j);
542
1.04k
    _ijkScale(&kVec, ijk->k);
543
544
1.04k
    _ijkAdd(&iVec, &jVec, ijk);
545
1.04k
    _ijkAdd(ijk, &kVec, ijk);
546
547
1.04k
    _ijkNormalize(ijk);
548
1.04k
}
Unexecuted instantiation: vertex.c:_downAp7r
Unexecuted instantiation: directedEdge.c:_downAp7r
Unexecuted instantiation: iterators.c:_downAp7r
Unexecuted instantiation: faceijk.c:_downAp7r
Unexecuted instantiation: baseCells.c:_downAp7r
Unexecuted instantiation: algos.c:_downAp7r
Unexecuted instantiation: bbox.c:_downAp7r
Unexecuted instantiation: cellsToMultiPoly.c:_downAp7r
549
550
/**
551
 * Find the normalized ijk coordinates of the hex centered on the indicated
552
 * hex at the next finer aperture 3 counter-clockwise resolution. Works in
553
 * place.
554
 *
555
 * @param ijk The ijk coordinates.
556
 */
557
0
static inline void _downAp3(CoordIJK *ijk) {
558
    // res r unit vectors in res r+1
559
0
    CoordIJK iVec = {2, 0, 1};
560
0
    CoordIJK jVec = {1, 2, 0};
561
0
    CoordIJK kVec = {0, 1, 2};
562
563
0
    _ijkScale(&iVec, ijk->i);
564
0
    _ijkScale(&jVec, ijk->j);
565
0
    _ijkScale(&kVec, ijk->k);
566
567
0
    _ijkAdd(&iVec, &jVec, ijk);
568
0
    _ijkAdd(ijk, &kVec, ijk);
569
570
0
    _ijkNormalize(ijk);
571
0
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_downAp3
Unexecuted instantiation: h3Index.c:_downAp3
Unexecuted instantiation: vertex.c:_downAp3
Unexecuted instantiation: directedEdge.c:_downAp3
Unexecuted instantiation: iterators.c:_downAp3
Unexecuted instantiation: faceijk.c:_downAp3
Unexecuted instantiation: baseCells.c:_downAp3
Unexecuted instantiation: algos.c:_downAp3
Unexecuted instantiation: bbox.c:_downAp3
Unexecuted instantiation: cellsToMultiPoly.c:_downAp3
572
573
/**
574
 * Find the normalized ijk coordinates of the hex centered on the indicated
575
 * hex at the next finer aperture 3 clockwise resolution. Works in place.
576
 *
577
 * @param ijk The ijk coordinates.
578
 */
579
0
static inline void _downAp3r(CoordIJK *ijk) {
580
    // res r unit vectors in res r+1
581
0
    CoordIJK iVec = {2, 1, 0};
582
0
    CoordIJK jVec = {0, 2, 1};
583
0
    CoordIJK kVec = {1, 0, 2};
584
585
0
    _ijkScale(&iVec, ijk->i);
586
0
    _ijkScale(&jVec, ijk->j);
587
0
    _ijkScale(&kVec, ijk->k);
588
589
0
    _ijkAdd(&iVec, &jVec, ijk);
590
0
    _ijkAdd(ijk, &kVec, ijk);
591
592
0
    _ijkNormalize(ijk);
593
0
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_downAp3r
Unexecuted instantiation: h3Index.c:_downAp3r
Unexecuted instantiation: vertex.c:_downAp3r
Unexecuted instantiation: directedEdge.c:_downAp3r
Unexecuted instantiation: iterators.c:_downAp3r
Unexecuted instantiation: faceijk.c:_downAp3r
Unexecuted instantiation: baseCells.c:_downAp3r
Unexecuted instantiation: algos.c:_downAp3r
Unexecuted instantiation: bbox.c:_downAp3r
Unexecuted instantiation: cellsToMultiPoly.c:_downAp3r
594
595
/**
596
 * Find the normalized ijk coordinates of the hex in the specified digit
597
 * direction from the specified ijk coordinates. Works in place.
598
 *
599
 * @param ijk The ijk coordinates.
600
 * @param digit The digit direction from the original ijk coordinates.
601
 */
602
0
static inline void _neighbor(CoordIJK *ijk, Direction digit) {
603
0
    if (digit > CENTER_DIGIT && digit < NUM_DIGITS) {
604
0
        _ijkAdd(ijk, &UNIT_VECS[digit], ijk);
605
0
        _ijkNormalize(ijk);
606
0
    }
607
0
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_neighbor
Unexecuted instantiation: h3Index.c:_neighbor
Unexecuted instantiation: vertex.c:_neighbor
Unexecuted instantiation: directedEdge.c:_neighbor
Unexecuted instantiation: iterators.c:_neighbor
Unexecuted instantiation: faceijk.c:_neighbor
Unexecuted instantiation: baseCells.c:_neighbor
Unexecuted instantiation: algos.c:_neighbor
Unexecuted instantiation: bbox.c:_neighbor
Unexecuted instantiation: cellsToMultiPoly.c:_neighbor
608
609
/**
610
 * Rotates ijk coordinates 60 degrees counter-clockwise. Works in place.
611
 *
612
 * @param ijk The ijk coordinates.
613
 */
614
0
static inline void _ijkRotate60ccw(CoordIJK *ijk) {
615
    // unit vector rotations
616
0
    CoordIJK iVec = {1, 1, 0};
617
0
    CoordIJK jVec = {0, 1, 1};
618
0
    CoordIJK kVec = {1, 0, 1};
619
620
0
    _ijkScale(&iVec, ijk->i);
621
0
    _ijkScale(&jVec, ijk->j);
622
0
    _ijkScale(&kVec, ijk->k);
623
624
0
    _ijkAdd(&iVec, &jVec, ijk);
625
0
    _ijkAdd(ijk, &kVec, ijk);
626
627
0
    _ijkNormalize(ijk);
628
0
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_ijkRotate60ccw
Unexecuted instantiation: h3Index.c:_ijkRotate60ccw
Unexecuted instantiation: vertex.c:_ijkRotate60ccw
Unexecuted instantiation: directedEdge.c:_ijkRotate60ccw
Unexecuted instantiation: iterators.c:_ijkRotate60ccw
Unexecuted instantiation: faceijk.c:_ijkRotate60ccw
Unexecuted instantiation: baseCells.c:_ijkRotate60ccw
Unexecuted instantiation: algos.c:_ijkRotate60ccw
Unexecuted instantiation: bbox.c:_ijkRotate60ccw
Unexecuted instantiation: cellsToMultiPoly.c:_ijkRotate60ccw
629
630
/**
631
 * Rotates ijk coordinates 60 degrees clockwise. Works in place.
632
 *
633
 * @param ijk The ijk coordinates.
634
 */
635
0
static inline void _ijkRotate60cw(CoordIJK *ijk) {
636
    // unit vector rotations
637
0
    CoordIJK iVec = {1, 0, 1};
638
0
    CoordIJK jVec = {1, 1, 0};
639
0
    CoordIJK kVec = {0, 1, 1};
640
641
0
    _ijkScale(&iVec, ijk->i);
642
0
    _ijkScale(&jVec, ijk->j);
643
0
    _ijkScale(&kVec, ijk->k);
644
645
0
    _ijkAdd(&iVec, &jVec, ijk);
646
0
    _ijkAdd(ijk, &kVec, ijk);
647
648
0
    _ijkNormalize(ijk);
649
0
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_ijkRotate60cw
Unexecuted instantiation: h3Index.c:_ijkRotate60cw
Unexecuted instantiation: vertex.c:_ijkRotate60cw
Unexecuted instantiation: directedEdge.c:_ijkRotate60cw
Unexecuted instantiation: iterators.c:_ijkRotate60cw
Unexecuted instantiation: faceijk.c:_ijkRotate60cw
Unexecuted instantiation: baseCells.c:_ijkRotate60cw
Unexecuted instantiation: algos.c:_ijkRotate60cw
Unexecuted instantiation: bbox.c:_ijkRotate60cw
Unexecuted instantiation: cellsToMultiPoly.c:_ijkRotate60cw
650
651
/**
652
 * Rotates indexing digit 60 degrees counter-clockwise. Returns result.
653
 *
654
 * @param digit Indexing digit (between 1 and 6 inclusive)
655
 */
656
3.15k
static inline Direction _rotate60ccw(Direction digit) {
657
3.15k
    switch (digit) {
658
379
        case K_AXES_DIGIT:
659
379
            return IK_AXES_DIGIT;
660
360
        case IK_AXES_DIGIT:
661
360
            return I_AXES_DIGIT;
662
342
        case I_AXES_DIGIT:
663
342
            return IJ_AXES_DIGIT;
664
364
        case IJ_AXES_DIGIT:
665
364
            return J_AXES_DIGIT;
666
387
        case J_AXES_DIGIT:
667
387
            return JK_AXES_DIGIT;
668
391
        case JK_AXES_DIGIT:
669
391
            return K_AXES_DIGIT;
670
930
        default:
671
930
            return digit;
672
3.15k
    }
673
3.15k
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_rotate60ccw
h3Index.c:_rotate60ccw
Line
Count
Source
656
3.15k
static inline Direction _rotate60ccw(Direction digit) {
657
3.15k
    switch (digit) {
658
379
        case K_AXES_DIGIT:
659
379
            return IK_AXES_DIGIT;
660
360
        case IK_AXES_DIGIT:
661
360
            return I_AXES_DIGIT;
662
342
        case I_AXES_DIGIT:
663
342
            return IJ_AXES_DIGIT;
664
364
        case IJ_AXES_DIGIT:
665
364
            return J_AXES_DIGIT;
666
387
        case J_AXES_DIGIT:
667
387
            return JK_AXES_DIGIT;
668
391
        case JK_AXES_DIGIT:
669
391
            return K_AXES_DIGIT;
670
930
        default:
671
930
            return digit;
672
3.15k
    }
673
3.15k
}
Unexecuted instantiation: vertex.c:_rotate60ccw
Unexecuted instantiation: directedEdge.c:_rotate60ccw
Unexecuted instantiation: iterators.c:_rotate60ccw
Unexecuted instantiation: faceijk.c:_rotate60ccw
Unexecuted instantiation: baseCells.c:_rotate60ccw
Unexecuted instantiation: algos.c:_rotate60ccw
Unexecuted instantiation: bbox.c:_rotate60ccw
Unexecuted instantiation: cellsToMultiPoly.c:_rotate60ccw
674
675
/**
676
 * Rotates indexing digit 60 degrees clockwise. Returns result.
677
 *
678
 * @param digit Indexing digit (between 1 and 6 inclusive)
679
 */
680
110
static inline Direction _rotate60cw(Direction digit) {
681
110
    switch (digit) {
682
25
        case K_AXES_DIGIT:
683
25
            return JK_AXES_DIGIT;
684
5
        case JK_AXES_DIGIT:
685
5
            return J_AXES_DIGIT;
686
8
        case J_AXES_DIGIT:
687
8
            return IJ_AXES_DIGIT;
688
13
        case IJ_AXES_DIGIT:
689
13
            return I_AXES_DIGIT;
690
18
        case I_AXES_DIGIT:
691
18
            return IK_AXES_DIGIT;
692
16
        case IK_AXES_DIGIT:
693
16
            return K_AXES_DIGIT;
694
25
        default:
695
25
            return digit;
696
110
    }
697
110
}
Unexecuted instantiation: fuzzerLatLngToCell.c:_rotate60cw
h3Index.c:_rotate60cw
Line
Count
Source
680
110
static inline Direction _rotate60cw(Direction digit) {
681
110
    switch (digit) {
682
25
        case K_AXES_DIGIT:
683
25
            return JK_AXES_DIGIT;
684
5
        case JK_AXES_DIGIT:
685
5
            return J_AXES_DIGIT;
686
8
        case J_AXES_DIGIT:
687
8
            return IJ_AXES_DIGIT;
688
13
        case IJ_AXES_DIGIT:
689
13
            return I_AXES_DIGIT;
690
18
        case I_AXES_DIGIT:
691
18
            return IK_AXES_DIGIT;
692
16
        case IK_AXES_DIGIT:
693
16
            return K_AXES_DIGIT;
694
25
        default:
695
25
            return digit;
696
110
    }
697
110
}
Unexecuted instantiation: vertex.c:_rotate60cw
Unexecuted instantiation: directedEdge.c:_rotate60cw
Unexecuted instantiation: iterators.c:_rotate60cw
Unexecuted instantiation: faceijk.c:_rotate60cw
Unexecuted instantiation: baseCells.c:_rotate60cw
Unexecuted instantiation: algos.c:_rotate60cw
Unexecuted instantiation: bbox.c:_rotate60cw
Unexecuted instantiation: cellsToMultiPoly.c:_rotate60cw
698
699
/**
700
 * Finds the distance between the two coordinates. Returns result.
701
 *
702
 * @param c1 The first set of ijk coordinates.
703
 * @param c2 The second set of ijk coordinates.
704
 */
705
0
static inline int ijkDistance(const CoordIJK *c1, const CoordIJK *c2) {
706
0
    CoordIJK diff;
707
0
    _ijkSub(c1, c2, &diff);
708
0
    _ijkNormalize(&diff);
709
0
    CoordIJK absDiff = {abs(diff.i), abs(diff.j), abs(diff.k)};
710
0
    return MAX(absDiff.i, MAX(absDiff.j, absDiff.k));
711
0
}
Unexecuted instantiation: fuzzerLatLngToCell.c:ijkDistance
Unexecuted instantiation: h3Index.c:ijkDistance
Unexecuted instantiation: vertex.c:ijkDistance
Unexecuted instantiation: directedEdge.c:ijkDistance
Unexecuted instantiation: iterators.c:ijkDistance
Unexecuted instantiation: faceijk.c:ijkDistance
Unexecuted instantiation: baseCells.c:ijkDistance
Unexecuted instantiation: algos.c:ijkDistance
Unexecuted instantiation: bbox.c:ijkDistance
Unexecuted instantiation: cellsToMultiPoly.c:ijkDistance
712
713
/**
714
 * Transforms coordinates from the IJK+ coordinate system to the IJ coordinate
715
 * system.
716
 *
717
 * @param ijk The input IJK+ coordinates
718
 * @param ij The output IJ coordinates
719
 */
720
0
static inline void ijkToIj(const CoordIJK *ijk, CoordIJ *ij) {
721
0
    ij->i = ijk->i - ijk->k;
722
0
    ij->j = ijk->j - ijk->k;
723
0
}
Unexecuted instantiation: fuzzerLatLngToCell.c:ijkToIj
Unexecuted instantiation: h3Index.c:ijkToIj
Unexecuted instantiation: vertex.c:ijkToIj
Unexecuted instantiation: directedEdge.c:ijkToIj
Unexecuted instantiation: iterators.c:ijkToIj
Unexecuted instantiation: faceijk.c:ijkToIj
Unexecuted instantiation: baseCells.c:ijkToIj
Unexecuted instantiation: algos.c:ijkToIj
Unexecuted instantiation: bbox.c:ijkToIj
Unexecuted instantiation: cellsToMultiPoly.c:ijkToIj
724
725
/**
726
 * Transforms coordinates from the IJ coordinate system to the IJK+ coordinate
727
 * system.
728
 *
729
 * @param ij The input IJ coordinates
730
 * @param ijk The output IJK+ coordinates
731
 * @returns E_SUCCESS on success, E_FAILED if signed integer overflow would have
732
 * occurred.
733
 */
734
0
static inline H3Error ijToIjk(const CoordIJ *ij, CoordIJK *ijk) {
735
0
    ijk->i = ij->i;
736
0
    ijk->j = ij->j;
737
0
    ijk->k = 0;
738
0
739
0
    if (_ijkNormalizeCouldOverflow(ijk)) {
740
0
        return E_FAILED;
741
0
    }
742
0
743
0
    _ijkNormalize(ijk);
744
0
    return E_SUCCESS;
745
0
}
Unexecuted instantiation: fuzzerLatLngToCell.c:ijToIjk
Unexecuted instantiation: h3Index.c:ijToIjk
Unexecuted instantiation: vertex.c:ijToIjk
Unexecuted instantiation: directedEdge.c:ijToIjk
Unexecuted instantiation: iterators.c:ijToIjk
Unexecuted instantiation: faceijk.c:ijToIjk
Unexecuted instantiation: baseCells.c:ijToIjk
Unexecuted instantiation: algos.c:ijToIjk
Unexecuted instantiation: bbox.c:ijToIjk
Unexecuted instantiation: cellsToMultiPoly.c:ijToIjk
746
747
/**
748
 * Convert IJK coordinates to cube coordinates, in place
749
 * @param ijk Coordinate to convert
750
 */
751
0
static inline void ijkToCube(CoordIJK *ijk) {
752
0
    ijk->i = -ijk->i + ijk->k;
753
0
    ijk->j = ijk->j - ijk->k;
754
0
    ijk->k = -ijk->i - ijk->j;
755
0
}
Unexecuted instantiation: fuzzerLatLngToCell.c:ijkToCube
Unexecuted instantiation: h3Index.c:ijkToCube
Unexecuted instantiation: vertex.c:ijkToCube
Unexecuted instantiation: directedEdge.c:ijkToCube
Unexecuted instantiation: iterators.c:ijkToCube
Unexecuted instantiation: faceijk.c:ijkToCube
Unexecuted instantiation: baseCells.c:ijkToCube
Unexecuted instantiation: algos.c:ijkToCube
Unexecuted instantiation: bbox.c:ijkToCube
Unexecuted instantiation: cellsToMultiPoly.c:ijkToCube
756
757
/**
758
 * Convert cube coordinates to IJK coordinates, in place
759
 * @param ijk Coordinate to convert
760
 */
761
0
static inline void cubeToIjk(CoordIJK *ijk) {
762
0
    ijk->i = -ijk->i;
763
0
    ijk->k = 0;
764
0
    _ijkNormalize(ijk);
765
0
}
Unexecuted instantiation: fuzzerLatLngToCell.c:cubeToIjk
Unexecuted instantiation: h3Index.c:cubeToIjk
Unexecuted instantiation: vertex.c:cubeToIjk
Unexecuted instantiation: directedEdge.c:cubeToIjk
Unexecuted instantiation: iterators.c:cubeToIjk
Unexecuted instantiation: faceijk.c:cubeToIjk
Unexecuted instantiation: baseCells.c:cubeToIjk
Unexecuted instantiation: algos.c:cubeToIjk
Unexecuted instantiation: bbox.c:cubeToIjk
Unexecuted instantiation: cellsToMultiPoly.c:cubeToIjk
766
767
#undef INT32_MAX_3
768
769
#endif