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
106
static inline void _setIJK(CoordIJK *ijk, int i, int j, int k) {
104
106
    ijk->i = i;
105
106
    ijk->j = j;
106
106
    ijk->k = k;
107
106
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_setIJK
Unexecuted instantiation: directedEdge.c:_setIJK
faceijk.c:_setIJK
Line
Count
Source
103
106
static inline void _setIJK(CoordIJK *ijk, int i, int j, int k) {
104
106
    ijk->i = i;
105
106
    ijk->j = j;
106
106
    ijk->k = k;
107
106
}
Unexecuted instantiation: algos.c:_setIJK
Unexecuted instantiation: bbox.c:_setIJK
Unexecuted instantiation: h3Index.c:_setIJK
Unexecuted instantiation: vertex.c:_setIJK
Unexecuted instantiation: iterators.c:_setIJK
Unexecuted instantiation: baseCells.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
0
static inline int _ijkMatches(const CoordIJK *c1, const CoordIJK *c2) {
118
0
    return (c1->i == c2->i && c1->j == c2->j && c1->k == c2->k);
119
0
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_ijkMatches
Unexecuted instantiation: directedEdge.c:_ijkMatches
Unexecuted instantiation: faceijk.c:_ijkMatches
Unexecuted instantiation: algos.c:_ijkMatches
Unexecuted instantiation: bbox.c:_ijkMatches
Unexecuted instantiation: h3Index.c:_ijkMatches
Unexecuted instantiation: vertex.c:_ijkMatches
Unexecuted instantiation: iterators.c:_ijkMatches
Unexecuted instantiation: baseCells.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
34.2k
                           CoordIJK *sum) {
130
34.2k
    sum->i = h1->i + h2->i;
131
34.2k
    sum->j = h1->j + h2->j;
132
34.2k
    sum->k = h1->k + h2->k;
133
34.2k
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_ijkAdd
Unexecuted instantiation: directedEdge.c:_ijkAdd
faceijk.c:_ijkAdd
Line
Count
Source
129
11.5k
                           CoordIJK *sum) {
130
11.5k
    sum->i = h1->i + h2->i;
131
11.5k
    sum->j = h1->j + h2->j;
132
11.5k
    sum->k = h1->k + h2->k;
133
11.5k
}
Unexecuted instantiation: algos.c:_ijkAdd
Unexecuted instantiation: bbox.c:_ijkAdd
h3Index.c:_ijkAdd
Line
Count
Source
129
22.6k
                           CoordIJK *sum) {
130
22.6k
    sum->i = h1->i + h2->i;
131
22.6k
    sum->j = h1->j + h2->j;
132
22.6k
    sum->k = h1->k + h2->k;
133
22.6k
}
Unexecuted instantiation: vertex.c:_ijkAdd
Unexecuted instantiation: iterators.c:_ijkAdd
Unexecuted instantiation: baseCells.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
106
                           CoordIJK *diff) {
144
106
    diff->i = h1->i - h2->i;
145
106
    diff->j = h1->j - h2->j;
146
106
    diff->k = h1->k - h2->k;
147
106
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_ijkSub
Unexecuted instantiation: directedEdge.c:_ijkSub
faceijk.c:_ijkSub
Line
Count
Source
143
106
                           CoordIJK *diff) {
144
106
    diff->i = h1->i - h2->i;
145
106
    diff->j = h1->j - h2->j;
146
106
    diff->k = h1->k - h2->k;
147
106
}
Unexecuted instantiation: algos.c:_ijkSub
Unexecuted instantiation: bbox.c:_ijkSub
Unexecuted instantiation: h3Index.c:_ijkSub
Unexecuted instantiation: vertex.c:_ijkSub
Unexecuted instantiation: iterators.c:_ijkSub
Unexecuted instantiation: baseCells.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
39.4k
static inline void _ijkScale(CoordIJK *c, int factor) {
156
39.4k
    c->i *= factor;
157
39.4k
    c->j *= factor;
158
39.4k
    c->k *= factor;
159
39.4k
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_ijkScale
Unexecuted instantiation: directedEdge.c:_ijkScale
faceijk.c:_ijkScale
Line
Count
Source
155
13.2k
static inline void _ijkScale(CoordIJK *c, int factor) {
156
13.2k
    c->i *= factor;
157
13.2k
    c->j *= factor;
158
13.2k
    c->k *= factor;
159
13.2k
}
Unexecuted instantiation: algos.c:_ijkScale
Unexecuted instantiation: bbox.c:_ijkScale
h3Index.c:_ijkScale
Line
Count
Source
155
26.2k
static inline void _ijkScale(CoordIJK *c, int factor) {
156
26.2k
    c->i *= factor;
157
26.2k
    c->j *= factor;
158
26.2k
    c->k *= factor;
159
26.2k
}
Unexecuted instantiation: vertex.c:_ijkScale
Unexecuted instantiation: iterators.c:_ijkScale
Unexecuted instantiation: baseCells.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: fuzzerDirectedEdge.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: directedEdge.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: faceijk.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: algos.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: bbox.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: h3Index.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: vertex.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: iterators.c:_ijkNormalizeCouldOverflow
Unexecuted instantiation: baseCells.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
21.7k
static inline void _ijkNormalize(CoordIJK *c) {
208
    // remove any negative values
209
21.7k
    if (c->i < 0) {
210
180
        c->j -= c->i;
211
180
        c->k -= c->i;
212
180
        c->i = 0;
213
180
    }
214
215
21.7k
    if (c->j < 0) {
216
120
        c->i -= c->j;
217
120
        c->k -= c->j;
218
120
        c->j = 0;
219
120
    }
220
221
21.7k
    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
21.7k
    int min = c->i;
229
21.7k
    if (c->j < min) min = c->j;
230
21.7k
    if (c->k < min) min = c->k;
231
21.7k
    if (min > 0) {
232
16.3k
        c->i -= min;
233
16.3k
        c->j -= min;
234
16.3k
        c->k -= min;
235
16.3k
    }
236
21.7k
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_ijkNormalize
Unexecuted instantiation: directedEdge.c:_ijkNormalize
faceijk.c:_ijkNormalize
Line
Count
Source
207
7.30k
static inline void _ijkNormalize(CoordIJK *c) {
208
    // remove any negative values
209
7.30k
    if (c->i < 0) {
210
0
        c->j -= c->i;
211
0
        c->k -= c->i;
212
0
        c->i = 0;
213
0
    }
214
215
7.30k
    if (c->j < 0) {
216
0
        c->i -= c->j;
217
0
        c->k -= c->j;
218
0
        c->j = 0;
219
0
    }
220
221
7.30k
    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
7.30k
    int min = c->i;
229
7.30k
    if (c->j < min) min = c->j;
230
7.30k
    if (c->k < min) min = c->k;
231
7.30k
    if (min > 0) {
232
6.39k
        c->i -= min;
233
6.39k
        c->j -= min;
234
6.39k
        c->k -= min;
235
6.39k
    }
236
7.30k
}
Unexecuted instantiation: algos.c:_ijkNormalize
Unexecuted instantiation: bbox.c:_ijkNormalize
h3Index.c:_ijkNormalize
Line
Count
Source
207
14.4k
static inline void _ijkNormalize(CoordIJK *c) {
208
    // remove any negative values
209
14.4k
    if (c->i < 0) {
210
180
        c->j -= c->i;
211
180
        c->k -= c->i;
212
180
        c->i = 0;
213
180
    }
214
215
14.4k
    if (c->j < 0) {
216
120
        c->i -= c->j;
217
120
        c->k -= c->j;
218
120
        c->j = 0;
219
120
    }
220
221
14.4k
    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
14.4k
    int min = c->i;
229
14.4k
    if (c->j < min) min = c->j;
230
14.4k
    if (c->k < min) min = c->k;
231
14.4k
    if (min > 0) {
232
9.94k
        c->i -= min;
233
9.94k
        c->j -= min;
234
9.94k
        c->k -= min;
235
9.94k
    }
236
14.4k
}
Unexecuted instantiation: vertex.c:_ijkNormalize
Unexecuted instantiation: iterators.c:_ijkNormalize
Unexecuted instantiation: baseCells.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
824
static inline void _ijkToHex2d(const CoordIJK *h, Vec2d *v) {
245
824
    int i = h->i - h->k;
246
824
    int j = h->j - h->k;
247
248
824
    v->x = i - 0.5 * j;
249
824
    v->y = j * M_SQRT3_2;
250
824
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_ijkToHex2d
Unexecuted instantiation: directedEdge.c:_ijkToHex2d
faceijk.c:_ijkToHex2d
Line
Count
Source
244
824
static inline void _ijkToHex2d(const CoordIJK *h, Vec2d *v) {
245
824
    int i = h->i - h->k;
246
824
    int j = h->j - h->k;
247
248
824
    v->x = i - 0.5 * j;
249
824
    v->y = j * M_SQRT3_2;
250
824
}
Unexecuted instantiation: algos.c:_ijkToHex2d
Unexecuted instantiation: bbox.c:_ijkToHex2d
Unexecuted instantiation: h3Index.c:_ijkToHex2d
Unexecuted instantiation: vertex.c:_ijkToHex2d
Unexecuted instantiation: iterators.c:_ijkToHex2d
Unexecuted instantiation: baseCells.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
0
static inline void _hex2dToCoordIJK(const Vec2d *v, CoordIJK *h) {
260
0
    double a1, a2;
261
0
    double x1, x2;
262
0
    int m1, m2;
263
0
    double r1, r2;
264
265
    // quantize into the ij system and then normalize
266
0
    h->k = 0;
267
268
0
    a1 = fabsl(v->x);
269
0
    a2 = fabsl(v->y);
270
271
    // first do a reverse conversion
272
0
    x2 = a2 * M_RSIN60;
273
0
    x1 = a1 + x2 / 2.0;
274
275
    // check if we have the center of a hex
276
0
    m1 = (int)x1;
277
0
    m2 = (int)x2;
278
279
    // otherwise round correctly
280
0
    r1 = x1 - m1;
281
0
    r2 = x2 - m2;
282
283
0
    if (r1 < 0.5) {
284
0
        if (r1 < 1.0 / 3.0) {
285
0
            if (r2 < (1.0 + r1) / 2.0) {
286
0
                h->i = m1;
287
0
                h->j = m2;
288
0
            } else {
289
0
                h->i = m1;
290
0
                h->j = m2 + 1;
291
0
            }
292
0
        } else {
293
0
            if (r2 < (1.0 - r1)) {
294
0
                h->j = m2;
295
0
            } else {
296
0
                h->j = m2 + 1;
297
0
            }
298
299
0
            if ((1.0 - r1) <= r2 && r2 < (2.0 * r1)) {
300
0
                h->i = m1 + 1;
301
0
            } else {
302
0
                h->i = m1;
303
0
            }
304
0
        }
305
0
    } else {
306
0
        if (r1 < 2.0 / 3.0) {
307
0
            if (r2 < (1.0 - r1)) {
308
0
                h->j = m2;
309
0
            } else {
310
0
                h->j = m2 + 1;
311
0
            }
312
313
0
            if ((2.0 * r1 - 1.0) < r2 && r2 < (1.0 - r1)) {
314
0
                h->i = m1;
315
0
            } else {
316
0
                h->i = m1 + 1;
317
0
            }
318
0
        } else {
319
0
            if (r2 < (r1 / 2.0)) {
320
0
                h->i = m1 + 1;
321
0
                h->j = m2;
322
0
            } else {
323
0
                h->i = m1 + 1;
324
0
                h->j = m2 + 1;
325
0
            }
326
0
        }
327
0
    }
328
329
    // now fold across the axes if necessary
330
331
0
    if (v->x < 0.0) {
332
0
        if ((h->j % 2) == 0)  // even
333
0
        {
334
0
            long long int axisi = h->j / 2;
335
0
            long long int diff = h->i - axisi;
336
0
            h->i = (int)(h->i - 2.0 * diff);
337
0
        } else {
338
0
            long long int axisi = (h->j + 1) / 2;
339
0
            long long int diff = h->i - axisi;
340
0
            h->i = (int)(h->i - (2.0 * diff + 1));
341
0
        }
342
0
    }
343
344
0
    if (v->y < 0.0) {
345
0
        h->i = h->i - (2 * h->j + 1) / 2;
346
0
        h->j = -1 * h->j;
347
0
    }
348
349
0
    _ijkNormalize(h);
350
0
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_hex2dToCoordIJK
Unexecuted instantiation: directedEdge.c:_hex2dToCoordIJK
Unexecuted instantiation: faceijk.c:_hex2dToCoordIJK
Unexecuted instantiation: algos.c:_hex2dToCoordIJK
Unexecuted instantiation: bbox.c:_hex2dToCoordIJK
Unexecuted instantiation: h3Index.c:_hex2dToCoordIJK
Unexecuted instantiation: vertex.c:_hex2dToCoordIJK
Unexecuted instantiation: iterators.c:_hex2dToCoordIJK
Unexecuted instantiation: baseCells.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
0
static inline Direction _unitIjkToDigit(const CoordIJK *ijk) {
361
0
    CoordIJK c = *ijk;
362
0
    _ijkNormalize(&c);
363
364
0
    Direction digit = INVALID_DIGIT;
365
0
    for (Direction i = CENTER_DIGIT; i < NUM_DIGITS; i++) {
366
0
        if (_ijkMatches(&c, &UNIT_VECS[i])) {
367
0
            digit = i;
368
0
            break;
369
0
        }
370
0
    }
371
372
0
    return digit;
373
0
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_unitIjkToDigit
Unexecuted instantiation: directedEdge.c:_unitIjkToDigit
Unexecuted instantiation: faceijk.c:_unitIjkToDigit
Unexecuted instantiation: algos.c:_unitIjkToDigit
Unexecuted instantiation: bbox.c:_unitIjkToDigit
Unexecuted instantiation: h3Index.c:_unitIjkToDigit
Unexecuted instantiation: vertex.c:_unitIjkToDigit
Unexecuted instantiation: iterators.c:_unitIjkToDigit
Unexecuted instantiation: baseCells.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: fuzzerDirectedEdge.c:_upAp7Checked
Unexecuted instantiation: directedEdge.c:_upAp7Checked
Unexecuted instantiation: faceijk.c:_upAp7Checked
Unexecuted instantiation: algos.c:_upAp7Checked
Unexecuted instantiation: bbox.c:_upAp7Checked
Unexecuted instantiation: h3Index.c:_upAp7Checked
Unexecuted instantiation: vertex.c:_upAp7Checked
Unexecuted instantiation: iterators.c:_upAp7Checked
Unexecuted instantiation: baseCells.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: fuzzerDirectedEdge.c:_upAp7rChecked
Unexecuted instantiation: directedEdge.c:_upAp7rChecked
Unexecuted instantiation: faceijk.c:_upAp7rChecked
Unexecuted instantiation: algos.c:_upAp7rChecked
Unexecuted instantiation: bbox.c:_upAp7rChecked
Unexecuted instantiation: h3Index.c:_upAp7rChecked
Unexecuted instantiation: vertex.c:_upAp7rChecked
Unexecuted instantiation: iterators.c:_upAp7rChecked
Unexecuted instantiation: baseCells.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
0
static inline void _upAp7(CoordIJK *ijk) {
478
    // convert to CoordIJ
479
0
    int i = ijk->i - ijk->k;
480
0
    int j = ijk->j - ijk->k;
481
482
0
    ijk->i = (int)lround((3 * i - j) * M_ONESEVENTH);
483
0
    ijk->j = (int)lround((i + 2 * j) * M_ONESEVENTH);
484
0
    ijk->k = 0;
485
0
    _ijkNormalize(ijk);
486
0
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_upAp7
Unexecuted instantiation: directedEdge.c:_upAp7
Unexecuted instantiation: faceijk.c:_upAp7
Unexecuted instantiation: algos.c:_upAp7
Unexecuted instantiation: bbox.c:_upAp7
Unexecuted instantiation: h3Index.c:_upAp7
Unexecuted instantiation: vertex.c:_upAp7
Unexecuted instantiation: iterators.c:_upAp7
Unexecuted instantiation: baseCells.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
488
static inline void _upAp7r(CoordIJK *ijk) {
495
    // convert to CoordIJ
496
488
    int i = ijk->i - ijk->k;
497
488
    int j = ijk->j - ijk->k;
498
499
488
    ijk->i = (int)lround((2 * i + j) * M_ONESEVENTH);
500
488
    ijk->j = (int)lround((3 * j - i) * M_ONESEVENTH);
501
488
    ijk->k = 0;
502
488
    _ijkNormalize(ijk);
503
488
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_upAp7r
Unexecuted instantiation: directedEdge.c:_upAp7r
Unexecuted instantiation: faceijk.c:_upAp7r
Unexecuted instantiation: algos.c:_upAp7r
Unexecuted instantiation: bbox.c:_upAp7r
h3Index.c:_upAp7r
Line
Count
Source
494
488
static inline void _upAp7r(CoordIJK *ijk) {
495
    // convert to CoordIJ
496
488
    int i = ijk->i - ijk->k;
497
488
    int j = ijk->j - ijk->k;
498
499
488
    ijk->i = (int)lround((2 * i + j) * M_ONESEVENTH);
500
488
    ijk->j = (int)lround((3 * j - i) * M_ONESEVENTH);
501
488
    ijk->k = 0;
502
488
    _ijkNormalize(ijk);
503
488
}
Unexecuted instantiation: vertex.c:_upAp7r
Unexecuted instantiation: iterators.c:_upAp7r
Unexecuted instantiation: baseCells.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
4.37k
static inline void _downAp7(CoordIJK *ijk) {
513
    // res r unit vectors in res r+1
514
4.37k
    CoordIJK iVec = {3, 0, 1};
515
4.37k
    CoordIJK jVec = {1, 3, 0};
516
4.37k
    CoordIJK kVec = {0, 1, 3};
517
518
4.37k
    _ijkScale(&iVec, ijk->i);
519
4.37k
    _ijkScale(&jVec, ijk->j);
520
4.37k
    _ijkScale(&kVec, ijk->k);
521
522
4.37k
    _ijkAdd(&iVec, &jVec, ijk);
523
4.37k
    _ijkAdd(ijk, &kVec, ijk);
524
525
4.37k
    _ijkNormalize(ijk);
526
4.37k
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_downAp7
Unexecuted instantiation: directedEdge.c:_downAp7
Unexecuted instantiation: faceijk.c:_downAp7
Unexecuted instantiation: algos.c:_downAp7
Unexecuted instantiation: bbox.c:_downAp7
h3Index.c:_downAp7
Line
Count
Source
512
4.37k
static inline void _downAp7(CoordIJK *ijk) {
513
    // res r unit vectors in res r+1
514
4.37k
    CoordIJK iVec = {3, 0, 1};
515
4.37k
    CoordIJK jVec = {1, 3, 0};
516
4.37k
    CoordIJK kVec = {0, 1, 3};
517
518
4.37k
    _ijkScale(&iVec, ijk->i);
519
4.37k
    _ijkScale(&jVec, ijk->j);
520
4.37k
    _ijkScale(&kVec, ijk->k);
521
522
4.37k
    _ijkAdd(&iVec, &jVec, ijk);
523
4.37k
    _ijkAdd(ijk, &kVec, ijk);
524
525
4.37k
    _ijkNormalize(ijk);
526
4.37k
}
Unexecuted instantiation: vertex.c:_downAp7
Unexecuted instantiation: iterators.c:_downAp7
Unexecuted instantiation: baseCells.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
4.68k
static inline void _downAp7r(CoordIJK *ijk) {
535
    // res r unit vectors in res r+1
536
4.68k
    CoordIJK iVec = {3, 1, 0};
537
4.68k
    CoordIJK jVec = {0, 3, 1};
538
4.68k
    CoordIJK kVec = {1, 0, 3};
539
540
4.68k
    _ijkScale(&iVec, ijk->i);
541
4.68k
    _ijkScale(&jVec, ijk->j);
542
4.68k
    _ijkScale(&kVec, ijk->k);
543
544
4.68k
    _ijkAdd(&iVec, &jVec, ijk);
545
4.68k
    _ijkAdd(ijk, &kVec, ijk);
546
547
4.68k
    _ijkNormalize(ijk);
548
4.68k
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_downAp7r
Unexecuted instantiation: directedEdge.c:_downAp7r
faceijk.c:_downAp7r
Line
Count
Source
534
321
static inline void _downAp7r(CoordIJK *ijk) {
535
    // res r unit vectors in res r+1
536
321
    CoordIJK iVec = {3, 1, 0};
537
321
    CoordIJK jVec = {0, 3, 1};
538
321
    CoordIJK kVec = {1, 0, 3};
539
540
321
    _ijkScale(&iVec, ijk->i);
541
321
    _ijkScale(&jVec, ijk->j);
542
321
    _ijkScale(&kVec, ijk->k);
543
544
321
    _ijkAdd(&iVec, &jVec, ijk);
545
321
    _ijkAdd(ijk, &kVec, ijk);
546
547
321
    _ijkNormalize(ijk);
548
321
}
Unexecuted instantiation: algos.c:_downAp7r
Unexecuted instantiation: bbox.c:_downAp7r
h3Index.c:_downAp7r
Line
Count
Source
534
4.36k
static inline void _downAp7r(CoordIJK *ijk) {
535
    // res r unit vectors in res r+1
536
4.36k
    CoordIJK iVec = {3, 1, 0};
537
4.36k
    CoordIJK jVec = {0, 3, 1};
538
4.36k
    CoordIJK kVec = {1, 0, 3};
539
540
4.36k
    _ijkScale(&iVec, ijk->i);
541
4.36k
    _ijkScale(&jVec, ijk->j);
542
4.36k
    _ijkScale(&kVec, ijk->k);
543
544
4.36k
    _ijkAdd(&iVec, &jVec, ijk);
545
4.36k
    _ijkAdd(ijk, &kVec, ijk);
546
547
4.36k
    _ijkNormalize(ijk);
548
4.36k
}
Unexecuted instantiation: vertex.c:_downAp7r
Unexecuted instantiation: iterators.c:_downAp7r
Unexecuted instantiation: baseCells.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
383
static inline void _downAp3(CoordIJK *ijk) {
558
    // res r unit vectors in res r+1
559
383
    CoordIJK iVec = {2, 0, 1};
560
383
    CoordIJK jVec = {1, 2, 0};
561
383
    CoordIJK kVec = {0, 1, 2};
562
563
383
    _ijkScale(&iVec, ijk->i);
564
383
    _ijkScale(&jVec, ijk->j);
565
383
    _ijkScale(&kVec, ijk->k);
566
567
383
    _ijkAdd(&iVec, &jVec, ijk);
568
383
    _ijkAdd(ijk, &kVec, ijk);
569
570
383
    _ijkNormalize(ijk);
571
383
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_downAp3
Unexecuted instantiation: directedEdge.c:_downAp3
faceijk.c:_downAp3
Line
Count
Source
557
383
static inline void _downAp3(CoordIJK *ijk) {
558
    // res r unit vectors in res r+1
559
383
    CoordIJK iVec = {2, 0, 1};
560
383
    CoordIJK jVec = {1, 2, 0};
561
383
    CoordIJK kVec = {0, 1, 2};
562
563
383
    _ijkScale(&iVec, ijk->i);
564
383
    _ijkScale(&jVec, ijk->j);
565
383
    _ijkScale(&kVec, ijk->k);
566
567
383
    _ijkAdd(&iVec, &jVec, ijk);
568
383
    _ijkAdd(ijk, &kVec, ijk);
569
570
383
    _ijkNormalize(ijk);
571
383
}
Unexecuted instantiation: algos.c:_downAp3
Unexecuted instantiation: bbox.c:_downAp3
Unexecuted instantiation: h3Index.c:_downAp3
Unexecuted instantiation: vertex.c:_downAp3
Unexecuted instantiation: iterators.c:_downAp3
Unexecuted instantiation: baseCells.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
383
static inline void _downAp3r(CoordIJK *ijk) {
580
    // res r unit vectors in res r+1
581
383
    CoordIJK iVec = {2, 1, 0};
582
383
    CoordIJK jVec = {0, 2, 1};
583
383
    CoordIJK kVec = {1, 0, 2};
584
585
383
    _ijkScale(&iVec, ijk->i);
586
383
    _ijkScale(&jVec, ijk->j);
587
383
    _ijkScale(&kVec, ijk->k);
588
589
383
    _ijkAdd(&iVec, &jVec, ijk);
590
383
    _ijkAdd(ijk, &kVec, ijk);
591
592
383
    _ijkNormalize(ijk);
593
383
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_downAp3r
Unexecuted instantiation: directedEdge.c:_downAp3r
faceijk.c:_downAp3r
Line
Count
Source
579
383
static inline void _downAp3r(CoordIJK *ijk) {
580
    // res r unit vectors in res r+1
581
383
    CoordIJK iVec = {2, 1, 0};
582
383
    CoordIJK jVec = {0, 2, 1};
583
383
    CoordIJK kVec = {1, 0, 2};
584
585
383
    _ijkScale(&iVec, ijk->i);
586
383
    _ijkScale(&jVec, ijk->j);
587
383
    _ijkScale(&kVec, ijk->k);
588
589
383
    _ijkAdd(&iVec, &jVec, ijk);
590
383
    _ijkAdd(ijk, &kVec, ijk);
591
592
383
    _ijkNormalize(ijk);
593
383
}
Unexecuted instantiation: algos.c:_downAp3r
Unexecuted instantiation: bbox.c:_downAp3r
Unexecuted instantiation: h3Index.c:_downAp3r
Unexecuted instantiation: vertex.c:_downAp3r
Unexecuted instantiation: iterators.c:_downAp3r
Unexecuted instantiation: baseCells.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
8.11k
static inline void _neighbor(CoordIJK *ijk, Direction digit) {
603
8.11k
    if (digit > CENTER_DIGIT && digit < NUM_DIGITS) {
604
5.22k
        _ijkAdd(ijk, &UNIT_VECS[digit], ijk);
605
5.22k
        _ijkNormalize(ijk);
606
5.22k
    }
607
8.11k
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_neighbor
Unexecuted instantiation: directedEdge.c:_neighbor
Unexecuted instantiation: faceijk.c:_neighbor
Unexecuted instantiation: algos.c:_neighbor
Unexecuted instantiation: bbox.c:_neighbor
h3Index.c:_neighbor
Line
Count
Source
602
8.11k
static inline void _neighbor(CoordIJK *ijk, Direction digit) {
603
8.11k
    if (digit > CENTER_DIGIT && digit < NUM_DIGITS) {
604
5.22k
        _ijkAdd(ijk, &UNIT_VECS[digit], ijk);
605
5.22k
        _ijkNormalize(ijk);
606
5.22k
    }
607
8.11k
}
Unexecuted instantiation: vertex.c:_neighbor
Unexecuted instantiation: iterators.c:_neighbor
Unexecuted instantiation: baseCells.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
2.91k
static inline void _ijkRotate60ccw(CoordIJK *ijk) {
615
    // unit vector rotations
616
2.91k
    CoordIJK iVec = {1, 1, 0};
617
2.91k
    CoordIJK jVec = {0, 1, 1};
618
2.91k
    CoordIJK kVec = {1, 0, 1};
619
620
2.91k
    _ijkScale(&iVec, ijk->i);
621
2.91k
    _ijkScale(&jVec, ijk->j);
622
2.91k
    _ijkScale(&kVec, ijk->k);
623
624
2.91k
    _ijkAdd(&iVec, &jVec, ijk);
625
2.91k
    _ijkAdd(ijk, &kVec, ijk);
626
627
2.91k
    _ijkNormalize(ijk);
628
2.91k
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_ijkRotate60ccw
Unexecuted instantiation: directedEdge.c:_ijkRotate60ccw
faceijk.c:_ijkRotate60ccw
Line
Count
Source
614
2.91k
static inline void _ijkRotate60ccw(CoordIJK *ijk) {
615
    // unit vector rotations
616
2.91k
    CoordIJK iVec = {1, 1, 0};
617
2.91k
    CoordIJK jVec = {0, 1, 1};
618
2.91k
    CoordIJK kVec = {1, 0, 1};
619
620
2.91k
    _ijkScale(&iVec, ijk->i);
621
2.91k
    _ijkScale(&jVec, ijk->j);
622
2.91k
    _ijkScale(&kVec, ijk->k);
623
624
2.91k
    _ijkAdd(&iVec, &jVec, ijk);
625
2.91k
    _ijkAdd(ijk, &kVec, ijk);
626
627
2.91k
    _ijkNormalize(ijk);
628
2.91k
}
Unexecuted instantiation: algos.c:_ijkRotate60ccw
Unexecuted instantiation: bbox.c:_ijkRotate60ccw
Unexecuted instantiation: h3Index.c:_ijkRotate60ccw
Unexecuted instantiation: vertex.c:_ijkRotate60ccw
Unexecuted instantiation: iterators.c:_ijkRotate60ccw
Unexecuted instantiation: baseCells.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
106
static inline void _ijkRotate60cw(CoordIJK *ijk) {
636
    // unit vector rotations
637
106
    CoordIJK iVec = {1, 0, 1};
638
106
    CoordIJK jVec = {1, 1, 0};
639
106
    CoordIJK kVec = {0, 1, 1};
640
641
106
    _ijkScale(&iVec, ijk->i);
642
106
    _ijkScale(&jVec, ijk->j);
643
106
    _ijkScale(&kVec, ijk->k);
644
645
106
    _ijkAdd(&iVec, &jVec, ijk);
646
106
    _ijkAdd(ijk, &kVec, ijk);
647
648
106
    _ijkNormalize(ijk);
649
106
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_ijkRotate60cw
Unexecuted instantiation: directedEdge.c:_ijkRotate60cw
faceijk.c:_ijkRotate60cw
Line
Count
Source
635
106
static inline void _ijkRotate60cw(CoordIJK *ijk) {
636
    // unit vector rotations
637
106
    CoordIJK iVec = {1, 0, 1};
638
106
    CoordIJK jVec = {1, 1, 0};
639
106
    CoordIJK kVec = {0, 1, 1};
640
641
106
    _ijkScale(&iVec, ijk->i);
642
106
    _ijkScale(&jVec, ijk->j);
643
106
    _ijkScale(&kVec, ijk->k);
644
645
106
    _ijkAdd(&iVec, &jVec, ijk);
646
106
    _ijkAdd(ijk, &kVec, ijk);
647
648
106
    _ijkNormalize(ijk);
649
106
}
Unexecuted instantiation: algos.c:_ijkRotate60cw
Unexecuted instantiation: bbox.c:_ijkRotate60cw
Unexecuted instantiation: h3Index.c:_ijkRotate60cw
Unexecuted instantiation: vertex.c:_ijkRotate60cw
Unexecuted instantiation: iterators.c:_ijkRotate60cw
Unexecuted instantiation: baseCells.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
16.0k
static inline Direction _rotate60ccw(Direction digit) {
657
16.0k
    switch (digit) {
658
2.61k
        case K_AXES_DIGIT:
659
2.61k
            return IK_AXES_DIGIT;
660
2.10k
        case IK_AXES_DIGIT:
661
2.10k
            return I_AXES_DIGIT;
662
2.25k
        case I_AXES_DIGIT:
663
2.25k
            return IJ_AXES_DIGIT;
664
2.90k
        case IJ_AXES_DIGIT:
665
2.90k
            return J_AXES_DIGIT;
666
3.00k
        case J_AXES_DIGIT:
667
3.00k
            return JK_AXES_DIGIT;
668
2.89k
        case JK_AXES_DIGIT:
669
2.89k
            return K_AXES_DIGIT;
670
333
        default:
671
333
            return digit;
672
16.0k
    }
673
16.0k
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_rotate60ccw
Unexecuted instantiation: directedEdge.c:_rotate60ccw
Unexecuted instantiation: faceijk.c:_rotate60ccw
algos.c:_rotate60ccw
Line
Count
Source
656
207
static inline Direction _rotate60ccw(Direction digit) {
657
207
    switch (digit) {
658
31
        case K_AXES_DIGIT:
659
31
            return IK_AXES_DIGIT;
660
37
        case IK_AXES_DIGIT:
661
37
            return I_AXES_DIGIT;
662
36
        case I_AXES_DIGIT:
663
36
            return IJ_AXES_DIGIT;
664
37
        case IJ_AXES_DIGIT:
665
37
            return J_AXES_DIGIT;
666
35
        case J_AXES_DIGIT:
667
35
            return JK_AXES_DIGIT;
668
31
        case JK_AXES_DIGIT:
669
31
            return K_AXES_DIGIT;
670
0
        default:
671
0
            return digit;
672
207
    }
673
207
}
Unexecuted instantiation: bbox.c:_rotate60ccw
h3Index.c:_rotate60ccw
Line
Count
Source
656
15.8k
static inline Direction _rotate60ccw(Direction digit) {
657
15.8k
    switch (digit) {
658
2.58k
        case K_AXES_DIGIT:
659
2.58k
            return IK_AXES_DIGIT;
660
2.06k
        case IK_AXES_DIGIT:
661
2.06k
            return I_AXES_DIGIT;
662
2.21k
        case I_AXES_DIGIT:
663
2.21k
            return IJ_AXES_DIGIT;
664
2.86k
        case IJ_AXES_DIGIT:
665
2.86k
            return J_AXES_DIGIT;
666
2.96k
        case J_AXES_DIGIT:
667
2.96k
            return JK_AXES_DIGIT;
668
2.85k
        case JK_AXES_DIGIT:
669
2.85k
            return K_AXES_DIGIT;
670
333
        default:
671
333
            return digit;
672
15.8k
    }
673
15.8k
}
Unexecuted instantiation: vertex.c:_rotate60ccw
Unexecuted instantiation: iterators.c:_rotate60ccw
Unexecuted instantiation: baseCells.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
1.43k
static inline Direction _rotate60cw(Direction digit) {
681
1.43k
    switch (digit) {
682
256
        case K_AXES_DIGIT:
683
256
            return JK_AXES_DIGIT;
684
147
        case JK_AXES_DIGIT:
685
147
            return J_AXES_DIGIT;
686
107
        case J_AXES_DIGIT:
687
107
            return IJ_AXES_DIGIT;
688
137
        case IJ_AXES_DIGIT:
689
137
            return I_AXES_DIGIT;
690
195
        case I_AXES_DIGIT:
691
195
            return IK_AXES_DIGIT;
692
261
        case IK_AXES_DIGIT:
693
261
            return K_AXES_DIGIT;
694
335
        default:
695
335
            return digit;
696
1.43k
    }
697
1.43k
}
Unexecuted instantiation: fuzzerDirectedEdge.c:_rotate60cw
Unexecuted instantiation: directedEdge.c:_rotate60cw
Unexecuted instantiation: faceijk.c:_rotate60cw
Unexecuted instantiation: algos.c:_rotate60cw
Unexecuted instantiation: bbox.c:_rotate60cw
h3Index.c:_rotate60cw
Line
Count
Source
680
1.43k
static inline Direction _rotate60cw(Direction digit) {
681
1.43k
    switch (digit) {
682
256
        case K_AXES_DIGIT:
683
256
            return JK_AXES_DIGIT;
684
147
        case JK_AXES_DIGIT:
685
147
            return J_AXES_DIGIT;
686
107
        case J_AXES_DIGIT:
687
107
            return IJ_AXES_DIGIT;
688
137
        case IJ_AXES_DIGIT:
689
137
            return I_AXES_DIGIT;
690
195
        case I_AXES_DIGIT:
691
195
            return IK_AXES_DIGIT;
692
261
        case IK_AXES_DIGIT:
693
261
            return K_AXES_DIGIT;
694
335
        default:
695
335
            return digit;
696
1.43k
    }
697
1.43k
}
Unexecuted instantiation: vertex.c:_rotate60cw
Unexecuted instantiation: iterators.c:_rotate60cw
Unexecuted instantiation: baseCells.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: fuzzerDirectedEdge.c:ijkDistance
Unexecuted instantiation: directedEdge.c:ijkDistance
Unexecuted instantiation: faceijk.c:ijkDistance
Unexecuted instantiation: algos.c:ijkDistance
Unexecuted instantiation: bbox.c:ijkDistance
Unexecuted instantiation: h3Index.c:ijkDistance
Unexecuted instantiation: vertex.c:ijkDistance
Unexecuted instantiation: iterators.c:ijkDistance
Unexecuted instantiation: baseCells.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: fuzzerDirectedEdge.c:ijkToIj
Unexecuted instantiation: directedEdge.c:ijkToIj
Unexecuted instantiation: faceijk.c:ijkToIj
Unexecuted instantiation: algos.c:ijkToIj
Unexecuted instantiation: bbox.c:ijkToIj
Unexecuted instantiation: h3Index.c:ijkToIj
Unexecuted instantiation: vertex.c:ijkToIj
Unexecuted instantiation: iterators.c:ijkToIj
Unexecuted instantiation: baseCells.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: fuzzerDirectedEdge.c:ijToIjk
Unexecuted instantiation: directedEdge.c:ijToIjk
Unexecuted instantiation: faceijk.c:ijToIjk
Unexecuted instantiation: algos.c:ijToIjk
Unexecuted instantiation: bbox.c:ijToIjk
Unexecuted instantiation: h3Index.c:ijToIjk
Unexecuted instantiation: vertex.c:ijToIjk
Unexecuted instantiation: iterators.c:ijToIjk
Unexecuted instantiation: baseCells.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: fuzzerDirectedEdge.c:ijkToCube
Unexecuted instantiation: directedEdge.c:ijkToCube
Unexecuted instantiation: faceijk.c:ijkToCube
Unexecuted instantiation: algos.c:ijkToCube
Unexecuted instantiation: bbox.c:ijkToCube
Unexecuted instantiation: h3Index.c:ijkToCube
Unexecuted instantiation: vertex.c:ijkToCube
Unexecuted instantiation: iterators.c:ijkToCube
Unexecuted instantiation: baseCells.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: fuzzerDirectedEdge.c:cubeToIjk
Unexecuted instantiation: directedEdge.c:cubeToIjk
Unexecuted instantiation: faceijk.c:cubeToIjk
Unexecuted instantiation: algos.c:cubeToIjk
Unexecuted instantiation: bbox.c:cubeToIjk
Unexecuted instantiation: h3Index.c:cubeToIjk
Unexecuted instantiation: vertex.c:cubeToIjk
Unexecuted instantiation: iterators.c:cubeToIjk
Unexecuted instantiation: baseCells.c:cubeToIjk
Unexecuted instantiation: cellsToMultiPoly.c:cubeToIjk
766
767
#undef INT32_MAX_3
768
769
#endif