GCC Code Coverage Report


Directory: ./
File: lib/geogram/mesh/index.h
Date: 2026-09-07 02:37:58
Exec Total Coverage
Lines: 38 57 66.7%
Functions: 8 12 66.7%
Branches: 12 20 60.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40 #ifndef GEOGRAM_MESH_INDEX
41 #define GEOGRAM_MESH_INDEX
42
43 #include <geogram/basic/common.h>
44 #include <geogram/basic/numeric.h>
45 #include <geogram/basic/argused.h>
46 #include <geogram/basic/algorithm.h>
47 #include <iostream>
48
49 /**
50 * \file geogram/mesh/index.h
51 * \brief Classes for managing tuples of indices
52 */
53
54 namespace GEO {
55
56 /************************************************************************/
57
58 /**
59 * \brief A couple of two indices.
60 * \details Can be used as a key in associative data structures
61 * (std::map, std::set). The indices are defined by \p IndexType,
62 * generally signed or unsigned integers.
63 * \tparam IndexType type of the indices
64 */
65 template <class IndexType>
66 struct basic_bindex {
67
68 /**
69 * \brief The array of 2 indices
70 */
71 IndexType indices[2];
72
73 /**
74 * \brief This type is used to overload basic_bindex constructors with
75 * versions that keep the order of the stored indices.
76 */
77 enum KeepOrderType {
78 /** Value to pass to basic_bindex ordered constructor */
79 KEEP_ORDER
80 };
81
82 /**
83 * \brief Creates an uninitialized basic_bindex.
84 */
85 basic_bindex() {
86 }
87
88 /**
89 * \brief Creates a basic_bindex from two integers.
90 * \details The integers are reordered.
91 * \param[in] i first integer
92 * \param[in] j second integer
93 */
94 basic_bindex(
95 IndexType i,
96 IndexType j
97 ) {
98 if(i < j) {
99 indices[0] = i;
100 indices[1] = j;
101 } else {
102 indices[0] = j;
103 indices[1] = i;
104 }
105 }
106
107 /**
108 * \brief Creates a basic_bindex from two integers and
109 * keeps their order.
110 * \details The integers are not sorted.
111 * \param[in] i first integer
112 * \param[in] j second integer
113 * \param[in] order argument of type #KeepOrderType used to select the
114 * right constructor. Use \c basic_bindex::#KEEP_ORDER
115 * for this argument.
116 */
117 53805 basic_bindex(
118 IndexType i,
119 IndexType j,
120 KeepOrderType order
121 ) {
122 53805 geo_argused(order);
123 53805 indices[0] = i;
124 53805 indices[1] = j;
125 53805 }
126
127 /**
128 * \brief Compares two basic_bindex.
129 * \param[in] rhs the basic_bindex to compares this basic_bindex with.
130 * \return true if \p rhs is smaller than this basic_bindex according
131 * to the lexicographic order, false otherwise.
132 */
133 bool operator< (const basic_bindex<IndexType>& rhs) const {
134 if(indices[0] < rhs.indices[0]) {
135 return true;
136 }
137 if(indices[0] > rhs.indices[0]) {
138 return false;
139 }
140 if(indices[1] < rhs.indices[1]) {
141 return true;
142 }
143 return false;
144 }
145
146 /**
147 * \brief Compares two basic_bindex.
148 * \param[in] rhs the basic_bindex to compare this basic_bindex with.
149 * \return true of all indices of this basic_bindex correspond to
150 * the indices in \p rhs at the same positions, false otherwise.
151 */
152 bool operator== (const basic_bindex<IndexType>& rhs) const {
153 return
154 (indices[0] == rhs.indices[0]) &&
155 (indices[1] == rhs.indices[1]);
156 }
157
158 /**
159 * \brief Compares two basic_bindex.
160 * \param[in] rhs the basic_bindex to compare this basic_bindex with.
161 * \return true if one of the indices in \p rhs differs from
162 * the index in this basic_bindex at the same position,
163 * false otherwise.
164 */
165 bool operator!= (const basic_bindex<IndexType>& rhs) const {
166 return
167 (indices[0] != rhs.indices[0]) ||
168 (indices[1] != rhs.indices[1]);
169 }
170
171 /**
172 * \brief Constructs a basic_bindex from another one.
173 * \param[in] rhs the basic_bindex this basic_bindex
174 * should be copied from
175 */
176 basic_bindex(const basic_bindex<IndexType>& rhs) = default;
177
178 /**
179 * \brief Assigns a basic_bindex to this one.
180 * \param[in] rhs the basic_bindex this basic_bindex
181 * should be assigned from
182 * \return a reference to this basic_bindex
183 */
184 basic_bindex<IndexType>& operator= (
185 const basic_bindex<IndexType>& rhs
186 ) = default;
187
188 /**
189 * \brief Computes the inverse of a basic_bindex
190 * \details The inverse of a basic_bindex has the same indices but
191 * in reverse order.
192 * \param[in] b the basic_bindex
193 * \return a basic_bindex with the same indices as \p b but in reverse
194 * order.
195 */
196 static basic_bindex inverse(const basic_bindex<IndexType>& b) {
197 return basic_bindex(b.indices[1], b.indices[0], KEEP_ORDER);
198 }
199 };
200
201 /**
202 * \brief A basic_bindex made of 2 unsigned integers
203 * \relates basic_index
204 */
205 typedef basic_bindex<index_t> bindex;
206
207 /**
208 * \brief A basic_bindex made of 2 signed integers
209 * \relates basic_index
210 */
211 typedef basic_bindex<signed_index_t> signed_bindex;
212
213 /**
214 * \brief Writes a basic_bindex to a stream
215 * \details Displays all the indices of the basic_bindex \p B.
216 * \param[in] out the output stream
217 * \param[in] B the basic_bindex to write
218 * \tparam IndexType type of the indices
219 * \return a reference to the output stream \p out
220 * \relates basic_bindex
221 */
222 template <class IndexType>
223 inline std::ostream& operator<< (
224 std::ostream& out, const basic_bindex<IndexType>& B
225 ) {
226 return out << B.indices[0] << " " << B.indices[1];
227 }
228
229 /************************************************************************/
230
231 /**
232 * \brief A triple of three indices.
233 * \details Can be used as a key in associative data structures
234 * (std::map, std::set). The indices are defined by \p IndexType,
235 * generally signed or unsigned integers.
236 * \tparam IndexType type of the indices
237 */
238 template <class IndexType>
239 struct basic_trindex {
240
241 /**
242 * \brief The array of 3 indices
243 */
244 IndexType indices[3];
245
246 /**
247 * \brief This type is used to overload basic_trindex constructors with
248 * versions that keep the order of the stored indices.
249 */
250 enum KeepOrderType {
251 /** Value to pass to basic_trindex ordered constructor */
252 KEEP_ORDER
253 };
254
255 /**
256 * \brief Creates an uninitialized basic_trindex.
257 */
258 basic_trindex() {
259 }
260
261 /**
262 * \brief Creates a basic_trindex from three integers.
263 * \details The integers are reordered.
264 * \param[in] i first integer
265 * \param[in] j second integer
266 * \param[in] k third integer
267 */
268 7014226 basic_trindex(
269 IndexType i,
270 IndexType j,
271 IndexType k
272 ) {
273 7014226 indices[0] = i;
274 7014226 indices[1] = j;
275 7014226 indices[2] = k;
276 7014226 GEO::sort_3(indices);
277 7014226 }
278
279 /**
280 * \brief Creates a basic_trindex from three integers and
281 * keeps their order.
282 * \details The integers are not sorted.
283 * \param[in] i first integer
284 * \param[in] j second integer
285 * \param[in] k third integer
286 * \param[in] order argument of type #KeepOrderType used to select the
287 * right constructor. Use \c basic_trindex::#KEEP_ORDER
288 * for this argument.
289 */
290 183 basic_trindex(
291 IndexType i,
292 IndexType j,
293 IndexType k,
294 KeepOrderType order
295 ) {
296 183 geo_argused(order);
297 183 indices[0] = i;
298 183 indices[1] = j;
299 183 indices[2] = k;
300 183 }
301
302 /**
303 * \brief Compares two basic_trindex.
304 * \param[in] rhs the basic_trindex to compares this basic_trindex with.
305 * \return true if \p rhs is smaller than this basic_trindex according
306 * to the lexicographic order, false otherwise.
307 */
308 46699606 bool operator< (const basic_trindex<IndexType>& rhs) const {
309
2/2
✓ Branch 0 taken 87808336 times.
✓ Branch 1 taken 4046576 times.
91854912 for(index_t i = 0; i < 3; i++) {
310
2/2
✓ Branch 0 taken 30337524 times.
✓ Branch 1 taken 57470812 times.
87808336 if(indices[i] < rhs.indices[i]) {
311 30337524 return true;
312 }
313
2/2
✓ Branch 0 taken 12315506 times.
✓ Branch 1 taken 45155306 times.
57470812 if(indices[i] > rhs.indices[i]) {
314 12315506 return false;
315 }
316 }
317 4046576 return false;
318 }
319
320 /**
321 * \brief Compares two basic_trindex.
322 * \param[in] rhs the basic_trindex to compare this basic_trindex with.
323 * \return true of all indices of this basic_trindex correspond to
324 * the indices in \p rhs at the same positions, false otherwise.
325 */
326 bool operator== (const basic_trindex<IndexType>& rhs) const {
327 return
328 (indices[0] == rhs.indices[0]) &&
329 (indices[1] == rhs.indices[1]) &&
330 (indices[2] == rhs.indices[2]);
331 }
332
333 /**
334 * \brief Compares two basic_trindex.
335 * \param[in] rhs the basic_trindex to compare this basic_trindex with.
336 * \return true if one of the indices in \p rhs differs from
337 * the index in this basic_trindex at the same position,
338 * false otherwise.
339 */
340 bool operator!= (const basic_trindex<IndexType>& rhs) const {
341 return
342 (indices[0] != rhs.indices[0]) ||
343 (indices[1] != rhs.indices[1]) ||
344 (indices[2] != rhs.indices[2]);
345 }
346
347 /**
348 * \brief Constructs a basic_trindex from another one.
349 * \param[in] rhs the basic_trindex this basic_trindex
350 * should be copied from
351 */
352 basic_trindex(const basic_trindex<IndexType>& rhs) = default;
353
354 /**
355 * \brief Assigns a basic_trindex to this one.
356 * \param[in] rhs the basic_trindex this basic_trindex should
357 * be assigned from
358 * \return a reference to this basic_trindex
359 */
360 basic_trindex<IndexType>& operator= (
361 const basic_trindex<IndexType>& rhs
362 ) = default;
363
364 /**
365 * \brief Tests whether a basic_trindex has the same orientation
366 * as a triple of integers.
367 * \details Two basic_trindex have the same orientation if one of them
368 * is a circular permutation of the other one.
369 * \param[in] t the basic_trindex
370 * \param[in] i first index
371 * \param[in] j second index
372 * \param[in] k third index
373 * \return true if the indices in \p t are a circular permutation
374 * of (\p i, \p j, \p k), false otherwise.
375 */
376 static bool same_orientation(
377 const basic_trindex<IndexType>& t,
378 IndexType i, IndexType j, IndexType k
379 ) {
380 return
381 (t.indices[0] == i && t.indices[1] == j && t.indices[2] == k) ||
382 (t.indices[1] == i && t.indices[2] == j && t.indices[0] == k) ||
383 (t.indices[2] == i && t.indices[0] == j && t.indices[1] == k);
384 }
385
386 /**
387 * \brief Tests whether two basic_trindex have the same orientation.
388 * \details Two basic_trindex have the same orientation if one of them
389 * is a circular permutation of the other one.
390 * \param[in] t1 first basic_trindex
391 * \param[in] t2 second basic_trindex
392 * \return true if the indices in \p t2 are a circular permutation
393 * of the indices in \p t1, false otherwise.
394 */
395 static bool same_orientation(
396 const basic_trindex<IndexType>& t1,
397 const basic_trindex<IndexType>& t2
398 ) {
399 return same_orientation(
400 t1, t2.indices[0], t2.indices[1], t2.indices[2]
401 );
402 }
403
404 /**
405 * \brief Computes the inverse of a basic_trindex
406 * \details The inverse of a basic_trindex has the same indices but
407 * in reverse order.
408 * \param[in] t the basic_trindex
409 * \return a basic_trindex with the same indices as \p t but in reverse
410 * order.
411 */
412 static basic_trindex inverse(const basic_trindex<IndexType>& t) {
413 return basic_trindex(
414 t.indices[2], t.indices[1], t.indices[0], KEEP_ORDER
415 );
416 }
417 };
418
419 /**
420 * \brief A basic_trindex made of 3 unsigned integers
421 * \relates basic_index
422 */
423 typedef basic_trindex<index_t> trindex;
424
425 /**
426 * \brief A basic_trindex made of 3 signed integers
427 * \relates basic_index
428 */
429 typedef basic_trindex<signed_index_t> signed_trindex;
430
431 /**
432 * \brief Writes a basic_trindex to a stream
433 * \details Displays all the indices of the basic_trindex \p T.
434 * \param[in] out the output stream
435 * \param[in] T the basic_trindex to write
436 * \tparam IndexType type of the indices
437 * \return a reference to the output stream \p out
438 * \relates basic_trindex
439 */
440 template <class IndexType>
441 inline std::ostream& operator<< (
442 std::ostream& out, const basic_trindex<IndexType>& T
443 ) {
444 return out
445 << T.indices[0] << " " << T.indices[1] << " " << T.indices[2];
446 }
447
448 /************************************************************************/
449
450 /**
451 * \brief A tuple of four indices.
452 * \details Can be used as a key in associative data structures
453 * (std::map, std::set). The indices are defined by \p IndexType,
454 * generally signed or unsigned integers.
455 * \tparam IndexType type of the indices
456 */
457 template <class IndexType>
458 struct basic_quadindex {
459 /**
460 * \brief The array of 4 indices
461 */
462 IndexType indices[4];
463
464 /**
465 * \brief This type is used to overload basic_quadindex
466 * constructors with versions that keep the order of the
467 * stored indices.
468 */
469 enum KeepOrderType {
470 /** Value to pass to basic_quadindex ordered constructor */
471 KEEP_ORDER
472 };
473
474 /**
475 * \brief Constructs a new uninitialized basic_quadindex
476 */
477 basic_quadindex() {
478 }
479
480 /**
481 * \brief Creates a basic_quadindex from four integers.
482 * \details The integers are reordered.
483 * \param[in] i first integer
484 * \param[in] j second integer
485 * \param[in] k third integer
486 * \param[in] l fourth integer
487 */
488 1013747 basic_quadindex(
489 IndexType i,
490 IndexType j,
491 IndexType k,
492 IndexType l
493 ) {
494 1013747 indices[0] = i;
495 1013747 indices[1] = j;
496 1013747 indices[2] = k;
497 1013747 indices[3] = l;
498 1013747 GEO::sort_4(indices);
499 1013747 }
500
501 /**
502 * \brief Creates a basic_quadindex from four integers and
503 * keeps their order.
504 * \details The integers are not sorted.
505 * \param[in] i first integer
506 * \param[in] j second integer
507 * \param[in] k third integer
508 * \param[in] l fourth integer
509 * \param[in] order argument of type #KeepOrderType used to select the
510 * right constructor. Use \c basic_quadindex::#KEEP_ORDER for
511 * this argument.
512 */
513 basic_quadindex(
514 IndexType i,
515 IndexType j,
516 IndexType k,
517 IndexType l,
518 KeepOrderType order
519 ) {
520 geo_argused(order);
521 indices[0] = i;
522 indices[1] = j;
523 indices[2] = k;
524 indices[3] = l;
525 }
526
527 /**
528 * \brief Compares two basic_quadindex.
529 * \param[in] rhs the basic_quadindex to compares this
530 * basic_quadindex with.
531 * \return true if \p rhs is smaller than this basic_quadindex according
532 * to the lexicographic order, false otherwise.
533 */
534 15025666 bool operator< (const basic_quadindex<IndexType>& rhs) const {
535
2/2
✓ Branch 0 taken 21602898 times.
✓ Branch 1 taken 1402752 times.
23787505 for(index_t i = 0; i < 4; i++) {
536
2/2
✓ Branch 0 taken 7092724 times.
✓ Branch 1 taken 14510174 times.
22313243 if(indices[i] < rhs.indices[i]) {
537 7253327 return true;
538 }
539
2/2
✓ Branch 0 taken 6201172 times.
✓ Branch 1 taken 8309002 times.
15059916 if(indices[i] > rhs.indices[i]) {
540 6298077 return false;
541 }
542 }
543 1474262 return false;
544 }
545
546 /**
547 * \brief Compares two basic_quadindex.
548 * \param[in] rhs the basic_quadindex to compare this
549 * basic_quadindex with.
550 * \return true of all indices of this basic_quadindex correspond to
551 * the indices in \p rhs at the same positions, false otherwise.
552 */
553 bool operator== (const basic_quadindex<IndexType>& rhs) const {
554 return
555 (indices[0] == rhs.indices[0]) &&
556 (indices[1] == rhs.indices[1]) &&
557 (indices[2] == rhs.indices[2]) &&
558 (indices[3] == rhs.indices[3]);
559 }
560
561 /**
562 * \brief Compares two basic_quadindex.
563 * \param[in] rhs the basic_quadindex to compare this
564 * basic_quadindex with.
565 * \return true if one of the indices in \p rhs differs from
566 * the index in this basic_quadindex at the same position,
567 * false otherwise.
568 */
569 bool operator!= (const basic_quadindex<IndexType>& rhs) const {
570 return
571 (indices[0] != rhs.indices[0]) ||
572 (indices[1] != rhs.indices[1]) ||
573 (indices[2] != rhs.indices[2]) ||
574 (indices[3] != rhs.indices[3]);
575 }
576
577 /**
578 * \brief Constructs a basic_quadindex from another one.
579 * \param[in] rhs the basic_quadindex this basic_quadindex
580 * should be copied from
581 */
582 basic_quadindex(const basic_quadindex<IndexType>& rhs) = default;
583
584 /**
585 * \brief Assigns a basic_quadindex to this one.
586 * \param[in] rhs the basic_quadindex this basic_quadindex
587 * should be assigned from
588 * \return a reference to this basic_quadindex
589 */
590 basic_quadindex<IndexType>& operator= (
591 const basic_quadindex<IndexType>& rhs
592 ) = default;
593 };
594
595 /**
596 * \brief A basic_quadindex made of 4 unsigned integers
597 * \relates basic_index
598 */
599 typedef basic_quadindex<index_t> quadindex;
600
601 /**
602 * \brief A basic_quadindex made of 4 signed integers
603 * \relates basic_index
604 */
605 typedef basic_quadindex<signed_index_t> signed_quadindex;
606
607 /**
608 * \brief Writes a basic_quadindex to a stream
609 * \details Displays all the indices of the basic_quadindex \p Q.
610 * \param[in] out the output stream
611 * \param[in] Q the basic_quadindex to write
612 * \tparam IndexType type of the indices
613 * \return a reference to the output stream \p out
614 * \relates basic_quadindex
615 */
616 template <class IndexType>
617 inline std::ostream& operator<< (
618 std::ostream& out, const basic_quadindex<IndexType>& Q
619 ) {
620 return out
621 << Q.indices[0] << " " << Q.indices[1] << " "
622 << Q.indices[2] << " " << Q.indices[3];
623 }
624
625 /************************************************************************/
626 }
627
628 #endif
629