measur-tools-suite 1.0.13-beta.139 → 1.0.13-beta.141

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CONTRIBUTING.md CHANGED
@@ -1,19 +1,1260 @@
1
- # How to Contribute
1
+ # How to Contribute <!-- omit in toc -->
2
2
 
3
3
  This guide provides clear standards and best practices for contributing to this project. It covers coding style, documentation, formatting, and workflow expectations to help maintain high code quality, ensure long-term maintainability, and foster smooth collaboration among all contributors.
4
4
 
5
- ## [Style Guide](/contributing/style-guide.md)
5
+ [<h2> Style Guide </h2>](#style-guide)
6
6
 
7
7
  Follow this guide to make sure your contributions align with the project's coding standards. This will help ensure that your code is readable, maintainable, and consistent with the rest of the codebase.
8
8
 
9
- ## [Formatting](/contributing/formatting.md)
9
+ [<h2> Formatting </h2>](#formatting)
10
10
 
11
11
  Follow the formatting standards using clang-format to ensure a consistent code style across all C++ files. This helps maintain readability and reduces merge conflicts.
12
12
 
13
- ## [Documentation](/contributing/documentation.md)
13
+ [<h2> Documentation </h2>](#documentation)
14
14
 
15
15
  Follow these guidelines to document your code effectively using Doxygen. Proper documentation is crucial for understanding the codebase and facilitating collaboration.
16
16
 
17
- ## [Conventional Commits](/contributing/conventional-commits.md)
17
+ [<h2> Conventional Commits </h2>](#conventional-commits)
18
18
 
19
19
  Use Conventional Commits to structure your commit messages. This helps maintain a clear project history and makes it easier to understand the purpose of each change.
20
+
21
+ <!-- START mdsplit-ignore -->
22
+ <a id="index"></a>
23
+ <details open>
24
+ <summary><Strong>Index</Strong></summary>
25
+
26
+ - [Style Guide](#style-guide)
27
+ - [Header Files](#header-files)
28
+ - [Include Guards](#include-guards)
29
+ - [Include What You Use](#include-what-you-use)
30
+ - [Include Order](#include-order)
31
+ - [Function Definitions in Headers](#function-definitions-in-headers)
32
+ - [Scoping](#scoping)
33
+ - [Namespaces](#namespaces)
34
+ - [Local Variables](#local-variables)
35
+ - [Classes](#classes)
36
+ - [Access Control](#access-control)
37
+ - [Declaration Order](#declaration-order)
38
+ - [Structs](#structs)
39
+ - [Looping and Branching Statements](#looping-and-branching-statements)
40
+ - [Preincrement and Predecrement](#preincrement-and-predecrement)
41
+ - [Use of `const`](#use-of-const)
42
+ - [Naming](#naming)
43
+ - [Files](#files)
44
+ - [Namespaces](#namespaces-1)
45
+ - [Classes and Structs](#classes-and-structs)
46
+ - [Functions and Methods](#functions-and-methods)
47
+ - [Variables](#variables)
48
+ - [Member Variables](#member-variables)
49
+ - [Constants and Enums](#constants-and-enums)
50
+ - [Aliases](#aliases)
51
+ - [Templates](#templates)
52
+ - [Macros](#macros)
53
+ - [Comments](#comments)
54
+ - [When to comment](#when-to-comment)
55
+ - [Comment Style](#comment-style)
56
+ - [Formatting](#formatting)
57
+ - [Configuration](#configuration)
58
+ - [How to Format Code](#how-to-format-code)
59
+ - [Best Practices](#best-practices)
60
+ - [Documentation](#documentation)
61
+ - [Doxygen Commands](#doxygen-commands)
62
+ - [Doxygen Aliases](#doxygen-aliases)
63
+ - [Documenting Code](#documenting-code)
64
+ - [Math](#math)
65
+ - [Units](#units)
66
+ - [Formulas](#formulas)
67
+ - [Symbols](#symbols)
68
+ - [Files](#files-1)
69
+ - [Namespaces](#namespaces-2)
70
+ - [Classes \& Structs](#classes--structs)
71
+ - [Functions \& Methods](#functions--methods)
72
+ - [Member Variables](#member-variables-1)
73
+ - [Constants](#constants)
74
+ - [Enums](#enums)
75
+ - [Groups](#groups)
76
+ - [Generating Doxygen Documentation](#generating-doxygen-documentation)
77
+ - [Conventional Commits](#conventional-commits)
78
+ - [Commit Format](#commit-format)
79
+ - [Commit Types](#commit-types)
80
+ - [Commit Scopes](#commit-scopes)
81
+ - [Breaking Changes](#breaking-changes)
82
+
83
+ </details>
84
+ <!-- END mdsplit-ignore -->
85
+
86
+ # Style Guide
87
+
88
+ Use this guide to ensure your contributions align with the project's coding standards. It is loosely based on the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) and the [C++ Core Guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines), with some modifications to suit this project's needs.
89
+
90
+ <!-- START mdsplit-ignore -->
91
+ <a id="style-guide-index"></a>
92
+ <details open>
93
+ <summary><Strong>Index</Strong></summary>
94
+
95
+ - [Style Guide](#style-guide)
96
+ - [Header Files](#header-files)
97
+ - [Include Guards](#include-guards)
98
+ - [Include What You Use](#include-what-you-use)
99
+ - [Include Order](#include-order)
100
+ - [Function Definitions in Headers](#function-definitions-in-headers)
101
+ - [Scoping](#scoping)
102
+ - [Namespaces](#namespaces)
103
+ - [Local Variables](#local-variables)
104
+ - [Classes](#classes)
105
+ - [Access Control](#access-control)
106
+ - [Declaration Order](#declaration-order)
107
+ - [Structs](#structs)
108
+ - [Looping and Branching Statements](#looping-and-branching-statements)
109
+ - [Preincrement and Predecrement](#preincrement-and-predecrement)
110
+ - [Use of `const`](#use-of-const)
111
+ - [Naming](#naming)
112
+ - [Files](#files)
113
+ - [Namespaces](#namespaces-1)
114
+ - [Classes and Structs](#classes-and-structs)
115
+ - [Functions and Methods](#functions-and-methods)
116
+ - [Variables](#variables)
117
+ - [Member Variables](#member-variables)
118
+ - [Constants and Enums](#constants-and-enums)
119
+ - [Aliases](#aliases)
120
+ - [Templates](#templates)
121
+ - [Macros](#macros)
122
+ - [Comments](#comments)
123
+ - [When to comment](#when-to-comment)
124
+ - [Comment Style](#comment-style)
125
+
126
+ </details>
127
+ <!-- END mdsplit-ignore -->
128
+
129
+ ## Header Files
130
+
131
+ Every C++ source file (`.cpp`) should have a corresponding header file (`.h`). The header file contains declarations, while the source file contains definitions and implementations.
132
+
133
+ > [!NOTE]
134
+ > A common exception is unit tests, which may not require a separate header file. Small `.cpp` files containing just a `main()` function may also not have a corresponding header.
135
+
136
+ <!-- START mdsplit-ignore -->
137
+ **[Return to Index](#style-guide-index)**
138
+ <!-- END mdsplit-ignore -->
139
+
140
+ ### Include Guards
141
+
142
+ Every header file must have a `#pragma once` directive to prevent multiple inclusion of header files:
143
+
144
+ ```cpp
145
+ #pragma once
146
+
147
+ // other includes or declarations
148
+
149
+ // file content
150
+ ```
151
+
152
+ <!-- START mdsplit-ignore -->
153
+ **[Return to Index](#style-guide-index)**
154
+ <!-- END mdsplit-ignore -->
155
+
156
+ ### Include What You Use
157
+
158
+ Always include the header file that directly defines any symbol you use. Do not rely on headers being included indirectly through other files. This ensures that removing unnecessary includes will not break your code.
159
+
160
+ Avoid using forward declarations where possible. Instead, include the headers you need:
161
+
162
+ - Good:
163
+
164
+ ```cpp
165
+ #include "a.h" // Include the header that defines A
166
+
167
+ class B {
168
+ public:
169
+ void interactWithA(A* a);
170
+ }
171
+ ```
172
+
173
+ - Bad:
174
+
175
+ ```cpp
176
+ class A; // Forward declaration without full definition
177
+
178
+ class B {
179
+ public:
180
+ void interactWithA(A* a);
181
+ }
182
+ ```
183
+
184
+ <!-- START mdsplit-ignore -->
185
+ **[Return to Index](#style-guide-index)**
186
+ <!-- END mdsplit-ignore -->
187
+
188
+ ### Include Order
189
+
190
+ Use double quotes (`"header.h"`) for project and third-party headers, and angle brackets (`<vector>`) for standard library headers.
191
+
192
+ Include project headers relative to the source directory (e.g., `"module/header.h"`).
193
+
194
+ Clang-Format manages include order via the `.clang-format` file. The typical order is:
195
+ 1. Related header for the current file
196
+ 2. Standard library headers
197
+ 3. Third-party library headers
198
+ 4. Project-specific headers
199
+
200
+ List each third-party library as a separate category in `.clang-format`. Update `IncludeCategories` when adding new libraries.
201
+
202
+ <!-- START mdsplit-ignore -->
203
+ **[Return to Index](#style-guide-index)**
204
+ <!-- END mdsplit-ignore -->
205
+
206
+ ### Function Definitions in Headers
207
+
208
+ Define functions in header files only if they are short (10 lines or fewer) or are templates. Longer functions should go in `.cpp` files unless required in the header for technical reasons.
209
+
210
+ If a function must be defined in a header, keep its body out of the public section—use a private section, an `internal` namespace, or place it after a comment like `// Implementation details only below here`.
211
+
212
+ All header-defined functions must be ODR-safe: use `inline`, make them templates, or define them inside the class body.
213
+
214
+ Example:
215
+
216
+ ```cpp
217
+ template <typename T>
218
+ class Foo {
219
+ public:
220
+ // Short, ODR-safe function defined in header
221
+ int bar() const { return bar_; }
222
+
223
+ // Long function declared only; implementation in .cpp or below
224
+ void doSomething();
225
+
226
+ private:
227
+ int bar_;
228
+ };
229
+
230
+ // Implementation details only below here
231
+ template <typename T>
232
+ void Foo<T>::doSomething() {
233
+ // ... lengthy implementation ...
234
+ }
235
+ ```
236
+
237
+ <!-- START mdsplit-ignore -->
238
+ **[Return to Index](#style-guide-index)**
239
+ <!-- END mdsplit-ignore -->
240
+
241
+ ## Scoping
242
+
243
+ Scoping helps organize code, prevent name collisions, and manage visibility.
244
+
245
+ <!-- START mdsplit-ignore -->
246
+ **[Return to Index](#style-guide-index)**
247
+ <!-- END mdsplit-ignore -->
248
+
249
+ ### Namespaces
250
+
251
+ Place all code in a namespace, named after the project or its path:
252
+
253
+ ```cpp
254
+ namespace my_project {
255
+ // Code goes here
256
+ } // namespace my_project
257
+ ```
258
+
259
+ > [!NOTE]
260
+ > Avoid `using namespace ...;` and inline namespaces.
261
+
262
+ <!-- START mdsplit-ignore -->
263
+ **[Return to Index](#style-guide-index)**
264
+ <!-- END mdsplit-ignore -->
265
+
266
+ ### Local Variables
267
+
268
+ Declare variables in the narrowest scope possible, close to their first use and always initialize them at declaration:
269
+
270
+ ```cpp
271
+ void foo() {
272
+ int x = 42; // Declaration and initialization together.
273
+ // Use x...
274
+ }
275
+ ```
276
+
277
+ For objects used in loops, declare them outside the loop for efficiency:
278
+
279
+ ```cpp
280
+ Foo f;
281
+ for (int i = 0; i < 1000000; ++i) {
282
+ f.doSomething(i);
283
+ }
284
+ ```
285
+
286
+ <!-- START mdsplit-ignore -->
287
+ **[Return to Index](#style-guide-index)**
288
+ <!-- END mdsplit-ignore -->
289
+
290
+ ## Classes
291
+
292
+ Use `class` for types that encapsulate data and behavior. This section provides guidelines for writing classes in C++.
293
+
294
+ <!-- START mdsplit-ignore -->
295
+ **[Return to Index](#style-guide-index)**
296
+ <!-- END mdsplit-ignore -->
297
+
298
+ ### Access Control
299
+
300
+ Make data members `private` (except for constants) to protect invariants and encapsulation. Use accessor methods as needed.
301
+
302
+ <!-- START mdsplit-ignore -->
303
+ **[Return to Index](#style-guide-index)**
304
+ <!-- END mdsplit-ignore -->
305
+
306
+ ### Declaration Order
307
+
308
+ Start with `public:` members, then `protected:`, then `private:`. Omit empty sections.
309
+
310
+ Within each section, group declarations in this order:
311
+
312
+ 1. Types and aliases (`using`, `enum`, nested structs/classes, friends)
313
+ 2. (For structs) Non-static data members
314
+ 3. Static constants
315
+ 4. Factory functions
316
+ 5. Constructors and assignment operators
317
+ 6. Destructor
318
+ 7. Other functions
319
+ 8. Other data members
320
+
321
+ This keeps related items together and improves readability.
322
+
323
+ <!-- START mdsplit-ignore -->
324
+ **[Return to Index](#style-guide-index)**
325
+ <!-- END mdsplit-ignore -->
326
+
327
+ ## Structs
328
+
329
+ Use `struct` for passive data objects that carry data; use `class` for everything else.
330
+
331
+ Prefer to use a `struct` instead of a `std::pair` or `std::tuple` whenever the elements can have meaningful names.
332
+
333
+ Use pairs and tuples only in generic code where the elements do not have specific meanings, or when required for interoperability with existing code or APIs.
334
+
335
+ <!-- START mdsplit-ignore -->
336
+ **[Return to Index](#style-guide-index)**
337
+ <!-- END mdsplit-ignore -->
338
+
339
+ ## Looping and Branching Statements
340
+
341
+ Use braces for all control statements (`if`, `else`, `for`, `while`, `do`, `switch`), even for single-line bodies:
342
+
343
+ ```cpp
344
+ if (condition) {
345
+ doSomething();
346
+ }
347
+ else {
348
+ doSomethingElse();
349
+ }
350
+
351
+ while (condition) {
352
+ doSomething();
353
+ }
354
+
355
+ for (int i = 0; i < 10; ++i) {
356
+ doSomethingWith(i);
357
+ }
358
+
359
+ switch (var) {
360
+ case 0: {
361
+ foo();
362
+ break;
363
+ }
364
+ }
365
+ ```
366
+
367
+ <!-- START mdsplit-ignore -->
368
+ **[Return to Index](#style-guide-index)**
369
+ <!-- END mdsplit-ignore -->
370
+
371
+ ## Preincrement and Predecrement
372
+
373
+ Prefer prefix increment/decrement (`++i`, `--i`) over postfix (`i++`, `i--`) unless you need the value before the change:
374
+
375
+ ```cpp
376
+ // Good: preincrement
377
+ for (int i = 0; i < n; ++i) {
378
+ std::cout << i << std::endl;
379
+ }
380
+
381
+ // Necessary: postincrement
382
+ std::vector<int> vec = {10, 20, 30};
383
+ auto it = vec.begin();
384
+ while (it != vec.end()) {
385
+ std::cout << *it++ << std::endl; // Value needed before increment
386
+ }
387
+ ```
388
+
389
+ <!-- START mdsplit-ignore -->
390
+ **[Return to Index](#style-guide-index)**
391
+ <!-- END mdsplit-ignore -->
392
+
393
+ ## Use of `const`
394
+
395
+ Use `const` to indicate immutability and improve code safety. `constexpr` is preferred when a value is known at compile time.
396
+
397
+ ```cpp
398
+ void processData(const std::vector<int>& data) {
399
+ constexpr int threshold = 10; // Compile-time constant
400
+
401
+ // Use const to ensure data is not modified
402
+ for (const auto& item : data) {
403
+ if (item > threshold) {
404
+ // Do something with item
405
+ }
406
+ }
407
+ }
408
+ ```
409
+
410
+ <!-- START mdsplit-ignore -->
411
+ **[Return to Index](#style-guide-index)**
412
+ <!-- END mdsplit-ignore -->
413
+
414
+ ## Naming
415
+
416
+ Use the following naming conventions for various elements in the codebase to ensure consistency and readability.
417
+
418
+ <!-- START mdsplit-ignore -->
419
+ **[Return to Index](#style-guide-index)**
420
+ <!-- END mdsplit-ignore -->
421
+
422
+ ### Files
423
+
424
+ Use `snake_case` suffixed with the appropriate file extension (`.h`, `.hpp`, or `.cpp`) for file names (e.g., `my_class.h`, `my_class.cpp`).
425
+
426
+ > [!NOTE]
427
+ > This project uses `.h` for header files and `.cpp` for source files.
428
+
429
+ <!-- START mdsplit-ignore -->
430
+ **[Return to Index](#style-guide-index)**
431
+ <!-- END mdsplit-ignore -->
432
+
433
+ ### Namespaces
434
+
435
+ Use `snake_case` for namespace names (e.g., `my_project`, `utils`).
436
+
437
+ <!-- START mdsplit-ignore -->
438
+ **[Return to Index](#style-guide-index)**
439
+ <!-- END mdsplit-ignore -->
440
+
441
+ ### Classes and Structs
442
+
443
+ Use `PascalCase` for class and struct names (e.g., `MyClass`, `MyStruct`).
444
+
445
+ <!-- START mdsplit-ignore -->
446
+ **[Return to Index](#style-guide-index)**
447
+ <!-- END mdsplit-ignore -->
448
+
449
+ ### Functions and Methods
450
+
451
+ Use `camelCase` for function and method names (e.g., `myFunction`, `computeArea`).
452
+
453
+ Use verbs or verb phrases for function names to indicate actions.
454
+
455
+ - Accessor methods (getters) should be named after the property they return, without a `get` prefix (e.g., `eyeColor()`).
456
+ - Mutator methods (setters) should be named with a `set` prefix followed by the property name (e.g., `setEyeColor()`).
457
+
458
+ #### Example
459
+
460
+ ```cpp
461
+ class Dog {
462
+ public:
463
+ std::string eyeColor() const { return eye_color_; } // Accessor for eye_color_
464
+
465
+ void setEyeColor(const std::string& color) { eye_color_ = color; } // Mutator for eye_color_
466
+
467
+ private:
468
+ std::string eye_color_;
469
+ };
470
+ ```
471
+
472
+ <!-- START mdsplit-ignore -->
473
+ **[Return to Index](#style-guide-index)**
474
+ <!-- END mdsplit-ignore -->
475
+
476
+ ### Variables
477
+
478
+ Use `snake_case` for variable names and function parameters.
479
+
480
+ #### Example
481
+
482
+ ```cpp
483
+ void processData(int input_value) {
484
+ int local_variable = input_value * 2;
485
+ }
486
+ ```
487
+
488
+ <!-- START mdsplit-ignore -->
489
+ **[Return to Index](#style-guide-index)**
490
+ <!-- END mdsplit-ignore -->
491
+
492
+ ### Member Variables
493
+
494
+ Use `snake_case` for member variable names, with a trailing underscore (`_`) to distinguish them from local variables and parameters.
495
+
496
+ #### Example
497
+
498
+ ```cpp
499
+ class Dog {
500
+ private:
501
+ std::string name_;
502
+ int age_;
503
+ std::string eye_color_;
504
+ };
505
+ ```
506
+
507
+ Use `snake_case` for struct member variables without a trailing underscore.
508
+
509
+ #### Example
510
+
511
+ ```cpp
512
+ struct Point2 {
513
+ double x;
514
+ double y;
515
+ };
516
+ ```
517
+
518
+ <!-- START mdsplit-ignore -->
519
+ **[Return to Index](#style-guide-index)**
520
+ <!-- END mdsplit-ignore -->
521
+
522
+ ### Constants and Enums
523
+
524
+ Use `PascalCase` for enum names and `PascalCase` prefixed with `k` for constants and enum values.
525
+
526
+ #### Example
527
+
528
+ ```cpp
529
+ enum class Color {
530
+ kRed,
531
+ kGreen,
532
+ kBlue
533
+ };
534
+
535
+ const int kMaxValue = 100;
536
+ constexpr double kPi = 3.14159;
537
+ ```
538
+
539
+ <!-- START mdsplit-ignore -->
540
+ **[Return to Index](#style-guide-index)**
541
+ <!-- END mdsplit-ignore -->
542
+
543
+ ### Aliases
544
+
545
+ Use `PascalCase` for type aliases.
546
+
547
+ #### Example
548
+
549
+ ```cpp
550
+ using StringList = std::vector<std::string>;
551
+ ```
552
+
553
+ <!-- START mdsplit-ignore -->
554
+ **[Return to Index](#style-guide-index)**
555
+ <!-- END mdsplit-ignore -->
556
+
557
+ ### Templates
558
+
559
+ Use `PascalCase` for template parameters.
560
+
561
+ #### Example
562
+
563
+ ```cpp
564
+ template <typename InputType>
565
+ InputType processInput(InputType input);
566
+ ```
567
+
568
+ <!-- START mdsplit-ignore -->
569
+ **[Return to Index](#style-guide-index)**
570
+ <!-- END mdsplit-ignore -->
571
+
572
+ ### Macros
573
+
574
+ Use `UPPER_CASE` with a project-specific prefix for macro names.
575
+
576
+ #### Example
577
+
578
+ ```cpp
579
+ #define MYPROJECT_MAX(a, b) ((a) > (b) ? (a) : (b))
580
+ ```
581
+
582
+ > [!NOTE]
583
+ > Try to avoid using macros whenever possible. Macros can lead to hard-to-debug issues and are generally discouraged in modern C++. Instead, prefer `inline` or `constexpr` functions.
584
+
585
+ <!-- START mdsplit-ignore -->
586
+ **[Return to Index](#style-guide-index)**
587
+ <!-- END mdsplit-ignore -->
588
+
589
+ ## Comments
590
+
591
+ Comments are essential for understanding code. They help explain the intent behind code, document design decisions, and provide context for future maintainers. This section provides guidelines for writing effective comments.
592
+
593
+ <!-- START mdsplit-ignore -->
594
+ **[Return to Index](#style-guide-index)**
595
+ <!-- END mdsplit-ignore -->
596
+
597
+ ### When to comment
598
+
599
+ | Do comment when... | Avoid when... |
600
+ | -------------------------------------------------- | --------------------------------------------- |
601
+ | A non-obvious **algorithmic trick** needs context. | The code literally states the same thing. |
602
+ | A temporary **work-around or TODO** is present. | You can instead rename a variable or helper. |
603
+ | There is a subtle **invariant / side-effect**. | The function already documents the behaviour. |
604
+ | You’re **explaining why**, not *what*. | You’re restating the *what* (“increment i”). |
605
+
606
+ <!-- START mdsplit-ignore -->
607
+ **[Return to Index](#style-guide-index)**
608
+ <!-- END mdsplit-ignore -->
609
+
610
+ ### Comment Style
611
+
612
+ - **Place above** the line or block it explains—never to the right of long code.
613
+ - **Start with a capital letter** and **end with a period** if the sentence is complete.
614
+ - Use the `TODO(user, yyyy-mm-dd):` format for tasks.
615
+ - Keep lines short; wrap with the same `//` prefix.
616
+ - Prefer present tense and active voice.
617
+ - Be specific and actionable—avoid vague or generic comments.
618
+
619
+ ```cpp
620
+ // Compute signed area via Shoelace formula.
621
+ double area = polygonSignedArea(verts);
622
+
623
+ // Guard: polygon must be simple (no self-intersections).
624
+ if (hasSelfIntersection(verts)) return Err::kInvalid;
625
+
626
+ // TODO(alice, 2025-07-01): Replace O(n^2) intersection test with a sweep-line algorithm.
627
+ ```
628
+
629
+ <!-- START mdsplit-ignore -->
630
+ **[Return to Index](#style-guide-index)**
631
+ <!-- END mdsplit-ignore -->
632
+
633
+ # Formatting
634
+
635
+ This project uses [clang-format](https://clang.llvm.org/docs/ClangFormat.html) to ensure a consistent code style across all C++ files.
636
+
637
+ <!-- START mdsplit-ignore -->
638
+ <a id="formatting-index"></a>
639
+ <details open>
640
+ <summary><Strong>Index</Strong></summary>
641
+
642
+ - [Formatting](#formatting)
643
+ - [Configuration](#configuration)
644
+ - [How to Format Code](#how-to-format-code)
645
+ - [Best Practices](#best-practices)
646
+
647
+ </details>
648
+ <!-- END mdsplit-ignore -->
649
+
650
+ ## Configuration
651
+
652
+ The formatting style is defined in the `.clang-format` file at the root of the repository. This file specifies rules for indentation, spacing, brace placement, include ordering, and more. The style is based on Google's C++ style guide with some customizations to fit the project's needs. To modify the formatting style, follow these steps:
653
+
654
+ 1. **Open** the `.clang-format` file in the root directory.
655
+ 2. **Experiment** with different settings using the [Clang-Format Configurator tool](https://clang-format-configurator.site/) or by editing the file directly.
656
+ 3. **Apply changes** by copying your updated configuration into the `.clang-format` file.
657
+ 4. **Reformat all code** to apply the new style. Use the following command to format every C++ source and header file in the project:
658
+ ```bash
659
+ find . -name '*.cpp' -o -name '*.h' | xargs clang-format -i --style=file
660
+ ```
661
+ 5. **Commit and review:** Commit only the style changes and immediately open a pull request. This keeps formatting changes separate from functional code changes, making reviews easier and reducing merge conflicts.
662
+
663
+ <!-- START mdsplit-ignore -->
664
+ **[Return to Index](#formatting-index)**
665
+ <!-- END mdsplit-ignore -->
666
+
667
+ ## How to Format Code
668
+
669
+ To format your code using clang-format, run the following command from the root directory of the project:
670
+
671
+ ```bash
672
+ clang-format -i --style=file <file1> <file2> ...
673
+ ```
674
+
675
+ - Replace `<file1> <file2> ...` with the files you want to format (e.g., `src/main.cpp include/util.h`).
676
+ - The `-i` flag edits files in-place.
677
+ - The `--style=file` flag tells clang-format to use the `.clang-format` configuration in the project root.
678
+
679
+ To format **all** C++ source and header files in the project, you can use:
680
+ ```bash
681
+ find . -name '*.cpp' -o -name '*.h' | xargs clang-format -i --style=file
682
+ ```
683
+
684
+ You can also configure your editor (such as VS Code, CLion, or Vim) to automatically format code on save using clang-format. Refer to your editor’s documentation or extensions/plugins for setup instructions.
685
+
686
+ <!-- START mdsplit-ignore -->
687
+ **[Return to Index](#formatting-index)**
688
+ <!-- END mdsplit-ignore -->
689
+
690
+ ## Best Practices
691
+
692
+ - **Format before committing:** Always run clang-format on your changes before submitting a pull request.
693
+ - **Editor integration:** Enable auto-format on save to avoid manual formatting.
694
+ - **Consistency:** Do not manually adjust formatting—let clang-format handle it.
695
+
696
+ If you have questions about the formatting rules or need help configuring your editor, ask in the project discussions or open an issue.
697
+
698
+ <!-- START mdsplit-ignore -->
699
+ **[Return to Index](#formatting-index)**
700
+ <!-- END mdsplit-ignore -->
701
+
702
+ # Documentation
703
+
704
+ This project uses [Doxygen](https://www.doxygen.nl/) to generate documentation from annotated source code. Doxygen comments are used to describe the purpose, behavior, and usage of classes, functions, and other entities in the codebase. Follow these guidelines to ensure your code is well-documented and easy to understand. Always use `@` for Doxygen commands.
705
+
706
+ <!-- START mdsplit-ignore -->
707
+ <a id="documentation-index"></a>
708
+ <details open>
709
+ <summary><Strong>Index</Strong></summary>
710
+
711
+ - [Documentation](#documentation)
712
+ - [Doxygen Commands](#doxygen-commands)
713
+ - [Doxygen Aliases](#doxygen-aliases)
714
+ - [Documenting Code](#documenting-code)
715
+ - [Math](#math)
716
+ - [Units](#units)
717
+ - [Formulas](#formulas)
718
+ - [Symbols](#symbols)
719
+ - [Files](#files-1)
720
+ - [Namespaces](#namespaces-2)
721
+ - [Classes \& Structs](#classes--structs)
722
+ - [Functions \& Methods](#functions--methods)
723
+ - [Member Variables](#member-variables-1)
724
+ - [Constants](#constants)
725
+ - [Enums](#enums)
726
+ - [Groups](#groups)
727
+ - [Generating Doxygen Documentation](#generating-doxygen-documentation)
728
+
729
+ </details>
730
+ <!-- END mdsplit-ignore -->
731
+
732
+ ## Doxygen Commands
733
+
734
+ All commands must start with `@`.
735
+
736
+ Useful Commands:
737
+ - `@file <name>`
738
+ - `@authors <authors>`
739
+ - `@ingroup <group-name>`
740
+ - `@defgroup <name> <group-title>`
741
+ - `@namespace <name>`
742
+ - `@class <name>`
743
+ - `@struct <name>`
744
+ - `@enum <name>`
745
+ - `@brief <brief description>`
746
+ - `@details <detailed description>`
747
+ - `@param[<direction>] <parameter-name> <parameter-description>`
748
+ - `@tparam <template-parameter-name> <description>`
749
+ - `@return <description>`
750
+ - `@throws <exception-object> <description>`
751
+ - `@note <text>`
752
+ - `@bug <description>`
753
+ - `@see <reference>`
754
+ - `@copyright <text>`
755
+ - `@cite <reference>`
756
+ - `@ref <reference> <display-text>`
757
+
758
+ <!-- START mdsplit-ignore -->
759
+ **[Return to Index](#documentation-index)**
760
+ <!-- END mdsplit-ignore -->
761
+
762
+ ## Doxygen Aliases
763
+
764
+ The following Doxygen aliases are defined in the `Doxyfile` to simplify common documentation tasks:
765
+ - `@math{<math expression>}`
766
+ - `@unitr{<unit expression>}`
767
+ - `@unitb{<unit expression>}`
768
+ - `@unitp{<unit expression>}`
769
+ - `@formula{<label>; <equation>}`
770
+ - `@symtable`
771
+ - `@symrow{<symbol>; <description>; <unit expression>}`
772
+ - `@endsymtable`
773
+
774
+ <!-- START mdsplit-ignore -->
775
+ **[Return to Index](#documentation-index)**
776
+ <!-- END mdsplit-ignore -->
777
+
778
+ ## Documenting Code
779
+
780
+ When documenting code, use Doxygen comments to describe the purpose and behavior of classes, functions, and other entities. Follow these guidelines to ensure your documentation is clear, consistent, and useful.
781
+
782
+ <!-- START mdsplit-ignore -->
783
+ **[Return to Index](#documentation-index)**
784
+ <!-- END mdsplit-ignore -->
785
+
786
+ ### Math
787
+
788
+ Use the `@math{<math expression>}` command to to write LaTeX-style mathematical expressions in your documentation.
789
+
790
+ #### Example
791
+
792
+ ```cpp
793
+ /**
794
+ * The speed of light in water is often denoted as @math{C_w}.
795
+ */
796
+ ```
797
+
798
+ <!-- START mdsplit-ignore -->
799
+ **[Return to Index](#documentation-index)**
800
+ <!-- END mdsplit-ignore -->
801
+
802
+ ### Units
803
+
804
+ Use the `@unitb{<unit expression>}` command to document units. The `@unitb{}` command uses the siunitx package to format units in LaTeX style and encloses them in brackets.
805
+
806
+ #### Example
807
+
808
+ ```cpp
809
+ /**
810
+ * The speed of light in water is often denoted as @math{C_w} and is approximately 2.25 @unitb{\meter\per\second}.
811
+ */
812
+ ```
813
+
814
+ <!-- START mdsplit-ignore -->
815
+ **[Return to Index](#documentation-index)**
816
+ <!-- END mdsplit-ignore -->
817
+
818
+ ### Formulas
819
+
820
+ Use the `@formula{<label>; <equation>}` command to document formulas. The command takes 2 arguments, separated by `;`:
821
+ 1. A label for the formula, which can be used to reference the formula in the documentation by using `\eqref{eq:<formula-label>}`.
822
+ - All labels are automatically prefixed with `eq:` to avoid conflicts.
823
+ 2. The formula itself, written in LaTeX syntax.
824
+
825
+ #### Example
826
+
827
+ ```cpp
828
+ /**
829
+ * The area of a circle can be computed using the formula:
830
+ * @formula{circle-area; A = \pi r^2}
831
+ */
832
+
833
+ /**
834
+ * Remember to use \eqref{eq:circle-area} to calculate the area of a circle.
835
+ */
836
+ ```
837
+
838
+ <!-- START mdsplit-ignore -->
839
+ **[Return to Index](#documentation-index)**
840
+ <!-- END mdsplit-ignore -->
841
+
842
+ ### Symbols
843
+
844
+ Use the `@symtable` and `@endsymtable` commands to create a table of symbols used in formulas. Each symbol is documented using the `@symrow{<symbol>; <description>; <unit expression>}` command, which takes three arguments, separated by `;`:
845
+ 1. The symbol itself, written in LaTeX syntax.
846
+ 2. A description of the symbol.
847
+ 3. The unit of the symbol, written in LaTeX syntax and formatted using the siunitx package.
848
+
849
+ #### Example
850
+
851
+ ```cpp
852
+ /**
853
+ * The area of a circle can be computed using the formula:
854
+ * @formula{circle-area; A = \pi r^2}
855
+ * where:
856
+ * @symtable
857
+ * @symrow{A; is the area of the circle; \meter\squared}
858
+ * @symrow{\pi; is the mathematical constant pi; 1}
859
+ * @symrow{r; is the radius of the circle; \meter}
860
+ * @endsymtable
861
+ */
862
+ ```
863
+
864
+ <!-- START mdsplit-ignore -->
865
+ **[Return to Index](#documentation-index)**
866
+ <!-- END mdsplit-ignore -->
867
+
868
+ ### Files
869
+
870
+ Use a **Doxygen block** at the very top of each header file to document the file's purpose, authors, and any relevant notes.
871
+
872
+ #### Relevant commands
873
+
874
+ - `@ingroup`
875
+ - `@file`
876
+ - `@authors`
877
+ - `@brief`
878
+ - `@details`
879
+ - `@note`
880
+ - `@see`
881
+ - `@copyright`
882
+
883
+ #### Example
884
+
885
+ ```cpp
886
+ /**
887
+ * @ingroup geometry
888
+ * @file polygon.h
889
+ * @authors Alice Brown, Carlos Diaz
890
+ * @brief Defines the Polygon class for representing simple 2-D polygons.
891
+ * @details This file contains the Polygon class, which provides methods for adding vertices, computing area, and checking point containment.
892
+ * @note The Polygon class assumes vertices are provided in counter-clockwise order.
893
+ * @see https://en.wikipedia.org/wiki/Polygon
894
+ * @copyright 2025 Geometry Toolkit
895
+ */
896
+ ```
897
+
898
+ <!-- START mdsplit-ignore -->
899
+ **[Return to Index](#documentation-index)**
900
+ <!-- END mdsplit-ignore -->
901
+
902
+ ### Namespaces
903
+
904
+ Use a **Doxygen block** above each namespace declaration in header files to document the namespace's purpose and contents.
905
+
906
+ #### Relevant commands
907
+
908
+ - `@ingroup`
909
+ - `@namespace`
910
+ - `@brief`
911
+ - `@details`
912
+ - `@note`
913
+ - `@see`
914
+
915
+ #### Example
916
+
917
+ ```cpp
918
+ /**
919
+ * @ingroup math
920
+ * @namespace constants
921
+ * @brief Defines mathematical constants used throughout the project.
922
+ */
923
+ namespace constants {}
924
+ ```
925
+
926
+ <!-- START mdsplit-ignore -->
927
+ **[Return to Index](#documentation-index)**
928
+ <!-- END mdsplit-ignore -->
929
+
930
+ ### Classes & Structs
931
+
932
+ Use a **Doxygen block** above each class or struct declaration in header files to document its purpose, behavior, and any important details. This applies to both classes and structs.
933
+
934
+ #### Relevant commands
935
+
936
+ - `@ingroup`
937
+ - `@class`
938
+ - `@struct`
939
+ - `@brief`
940
+ - `@details`
941
+ - `@tparam`
942
+ - `@note`
943
+ - `@bug`
944
+ - `@see`
945
+
946
+ #### Example
947
+
948
+ ```cpp
949
+ /**
950
+ * @ingroup geometry
951
+ * @struct Point2
952
+ * @brief Lightweight 2-D point with double precision.
953
+ */
954
+ struct Point2 {
955
+ double x {0.0}; ///< X coordinate
956
+ double y {0.0}; ///< Y coordinate
957
+ };
958
+
959
+ /**
960
+ * @ingroup geometry
961
+ * @class Polygon
962
+ * @brief Simple 2-D polygon representation.
963
+ * @details Stores vertices in counter-clockwise order.
964
+ * @note Capacity is fixed at construction.
965
+ * @bug AddVertex does not check for self-intersection.
966
+ */
967
+ class Polygon {
968
+ public:
969
+ /**
970
+ * @brief Constructs a Polygon with a maximum number of vertices.
971
+ * @param[in] max_vertices Maximum number of vertices allowed.
972
+ * @throws std::length_error If max_vertices is zero.
973
+ */
974
+ Polygon(std::size_t max_vertices);
975
+
976
+ /**
977
+ * @brief Adds a vertex to the polygon.
978
+ * @param[in] p New vertex in world coordinates.
979
+ * @return Index of the inserted vertex.
980
+ * @throws std::length_error If max_vertices reached.
981
+ */
982
+ std::size_t Polygon::addVertex(const Point2& p);
983
+
984
+ /**
985
+ * @brief Computes the signed area of the polygon.
986
+ * @details Uses the Shoelace formula to compute the area:
987
+ * @formula{polygon-area; A = \frac{1}{2} \sum_{i=1}^{n} (x_i y_{i+1} - x_{i+1} y_i)}
988
+ * where:
989
+ * @symtable
990
+ * @symrow{A; is the signed area of the polygon; \meter\squared}
991
+ * @symrow{n; is the number of vertices; 1}
992
+ * @symrow{x_i, y_i; are the coordinates of vertex i; \meter}
993
+ * @symrow{x_{n+1}, y_{n+1}; are the coordinates of vertex 1 (wrap-around); \meter}
994
+ * @endsymtable
995
+ * @note The area is positive if vertices are in counter-clockwise order.
996
+ * @return The signed area of the polygon.
997
+ */
998
+ double area() const;
999
+
1000
+ private:
1001
+ std::vector<Point2> vertices_; ///< Vertices in counter-clockwise order.
1002
+ };
1003
+ ```
1004
+
1005
+ <!-- START mdsplit-ignore -->
1006
+ **[Return to Index](#documentation-index)**
1007
+ <!-- END mdsplit-ignore -->
1008
+
1009
+ ### Functions & Methods
1010
+
1011
+ Use a **Doxygen block** above each public function or method declaration in header files. This applies to both free functions and member functions of classes or structs.
1012
+
1013
+ #### Relevant commands
1014
+
1015
+ - `@brief`
1016
+ - `@param[in]` **or** `param[out]` **or** `param[in,out]`
1017
+ - `@return`
1018
+ - `@details`
1019
+ - `@tparam`
1020
+ - `@throws`
1021
+ - `@note`
1022
+ - `@bug`
1023
+ - `@see`
1024
+
1025
+ #### Example
1026
+
1027
+ ```cpp
1028
+ /**
1029
+ * @brief Adds a vertex to the polygon.
1030
+ * @param[in] p New vertex in world coordinates.
1031
+ * @return Index of the inserted vertex.
1032
+ * @throws std::length_error If max_vertices reached.
1033
+ */
1034
+ std::size_t Polygon::addVertex(const Point2& p);
1035
+ ```
1036
+
1037
+ <!-- START mdsplit-ignore -->
1038
+ **[Return to Index](#documentation-index)**
1039
+ <!-- END mdsplit-ignore -->
1040
+
1041
+ ### Member Variables
1042
+
1043
+ Use inline comments with `///<` for one-line descriptions of data members. This applies to both classes and structs.
1044
+
1045
+ #### Example
1046
+
1047
+ ```cpp
1048
+ std::vector<Point2> vertices_; ///< Vertices in counter-clockwise order.
1049
+ ```
1050
+
1051
+ <!-- START mdsplit-ignore -->
1052
+ **[Return to Index](#documentation-index)**
1053
+ <!-- END mdsplit-ignore -->
1054
+
1055
+ ### Constants
1056
+
1057
+ Use inline comments with `///<` to document constants and their purpose.
1058
+
1059
+ #### Example
1060
+
1061
+ ```cpp
1062
+ constexpr double kPi = 3.141592653589793; ///< Circle ratio @unitb{radians}.
1063
+ inline constexpr Point2 kOrigin {0.0, 0.0}; ///< Reference point (0,0).
1064
+ ```
1065
+
1066
+ <!-- START mdsplit-ignore -->
1067
+ **[Return to Index](#documentation-index)**
1068
+ <!-- END mdsplit-ignore -->
1069
+
1070
+ ### Enums
1071
+
1072
+ Use a **Doxygen block** above each enum declaration in header files to document the enum type and its enumerators. Each enumerator should have an inline comment describing its purpose.
1073
+
1074
+ #### Relevant commands
1075
+
1076
+ - `@ingroup`
1077
+ - `@enum`
1078
+ - `@brief`
1079
+ - `@details`
1080
+ - `@note`
1081
+ - `@bug`
1082
+ - `@see`
1083
+
1084
+ #### Example
1085
+
1086
+ ```cpp
1087
+ /**
1088
+ * @ingroup geometry
1089
+ * @enum Axis
1090
+ * @brief Principal 3-D axes.
1091
+ */
1092
+ enum class Axis {
1093
+ kX, ///< X-axis
1094
+ kY, ///< Y-axis
1095
+ kZ ///< Z-axis
1096
+ };
1097
+ ```
1098
+
1099
+ <!-- START mdsplit-ignore -->
1100
+ **[Return to Index](#documentation-index)**
1101
+ <!-- END mdsplit-ignore -->
1102
+
1103
+ ### Groups
1104
+
1105
+ Use **Doxygen groups** to organize related namespaces, classes, and functions into logical modules.
1106
+
1107
+ Large groups must be defined in their own file (e.g., `math.dox`, `geometry.dox`) to avoid cluttering header files. These files should be placed in the `docs/` directory or one of its subdirectories.
1108
+
1109
+ #### Relevant commands
1110
+
1111
+ - `@defgroup`
1112
+ - `ingroup`
1113
+ - `@brief`
1114
+ - `@details`
1115
+ - `@copydoc`
1116
+ - `@see`
1117
+
1118
+ #### Example
1119
+
1120
+ ```cpp
1121
+ /**
1122
+ * @defgroup geometry Geometry
1123
+ * @ingroup math
1124
+ * @brief Geometry module for 2D and 3D shapes.
1125
+ */
1126
+ ```
1127
+
1128
+ <!-- START mdsplit-ignore -->
1129
+ **[Return to Index](#documentation-index)**
1130
+ <!-- END mdsplit-ignore -->
1131
+
1132
+ <!-- START mdsplit-ignore -->
1133
+ ## Generating Doxygen Documentation
1134
+
1135
+ Use the `Doxyfile` to configure Doxygen settings like input/output directories, file patterns, and more.
1136
+
1137
+ Use the `DoxygenLayout.xml` file to customize the layout of the generated documentation.
1138
+
1139
+ To generate the documentation, follow these steps:
1140
+ 1. Ensure [Doxygen](https://www.doxygen.nl/) is installed.
1141
+ 2. From the project root, run:
1142
+ ```bash
1143
+ doxygen Doxyfile
1144
+ ```
1145
+ 3. The generated HTML and/or LaTeX documentation will appear in the output directory specified in the `Doxyfile`.
1146
+
1147
+ **[Return to Index](#documentation-index)**
1148
+ <!-- END mdsplit-ignore -->
1149
+
1150
+ # Conventional Commits
1151
+
1152
+ This project follows the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification for commit messages to ensure clarity, consistency, and automation in version control. This helps in generating changelogs, automating releases, and improving collaboration among contributors.
1153
+
1154
+ <!-- START mdsplit-ignore -->
1155
+ <a id="conventional-commits-index"></a>
1156
+ <details open>
1157
+ <summary><Strong>Index</Strong></summary>
1158
+
1159
+ - [Conventional Commits](#conventional-commits)
1160
+ - [Commit Format](#commit-format)
1161
+ - [Commit Types](#commit-types)
1162
+ - [Commit Scopes](#commit-scopes)
1163
+ - [Breaking Changes](#breaking-changes)
1164
+
1165
+ </details>
1166
+ <!-- END mdsplit-ignore -->
1167
+
1168
+ ## Commit Format
1169
+
1170
+ Each commit message should follow this format:
1171
+
1172
+ ```
1173
+ <type>(<optional scopes>): <description>
1174
+
1175
+ <optional body>
1176
+
1177
+ <optional footer>
1178
+ ```
1179
+
1180
+ <!-- START mdsplit-ignore -->
1181
+ **[Return to Index](#conventional-commits-index)**
1182
+ <!-- END mdsplit-ignore -->
1183
+
1184
+ ## Commit Types
1185
+
1186
+ Commit types indicate the nature of the changes made in the commit. They help categorize changes and provide context for reviewers and automated tools. The following types are used:
1187
+
1188
+ - **`build`**: Changes that affect the build system or external dependencies.
1189
+ - **`chore`**: Other changes that don't modify src or tests (e.g., config updates).
1190
+ - **`ci`**: Changes to our CI configuration files and scripts.
1191
+ - **`docs`**: Documentation only changes.
1192
+ - **`feat`**: A new feature.
1193
+ - **`fix`**: A bug fix.
1194
+ - **`perf`**: A code change that improves performance.
1195
+ - **`refactor`**: A code change that neither fixes a bug nor adds a feature.
1196
+ - **`revert`**: Reverts a previous commit.
1197
+ - **`style`**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc).
1198
+ - **`test`**: Adding missing tests or correcting existing tests.
1199
+ - **`wip`**: Work in progress.
1200
+
1201
+ <!-- START mdsplit-ignore -->
1202
+ **[Return to Index](#conventional-commits-index)**
1203
+ <!-- END mdsplit-ignore -->
1204
+
1205
+ ## Commit Scopes
1206
+
1207
+ Scopes indicate the specific module, component, or area affected by the commit. They help in understanding the reach of changes within the codebase. The following scopes are used:
1208
+
1209
+ - **`clang-format`**
1210
+ - **`cli`**
1211
+ - **`cmake`**
1212
+ - **`compressedAir`**
1213
+ - **`databases`**
1214
+ - **`docs`**
1215
+ - **`doxygen`**
1216
+ - **`git`**
1217
+ - **`motorDriven`**
1218
+ - **`other`**
1219
+ - **`processCooling`**
1220
+ - **`processHeat`**
1221
+ - **`readme`**
1222
+ - **`steamModeler`**
1223
+ - **`tests`**
1224
+ - **`thirdParty`**
1225
+ - **`treasureHunt`**
1226
+ - **`util`**
1227
+ - **`wasteWater`**
1228
+ - **`vscode`**
1229
+
1230
+ When a commit affects multiple areas, you can specify multiple scopes separated by a comma and a space:
1231
+
1232
+ ```
1233
+ feat(cli, docs): add new command to generate reports
1234
+ ```
1235
+
1236
+ <!-- START mdsplit-ignore -->
1237
+ **[Return to Index](#conventional-commits-index)**
1238
+ <!-- END mdsplit-ignore -->
1239
+
1240
+ ## Breaking Changes
1241
+
1242
+ If a commit introduces breaking changes, it must be indicated in the `type/scope` prefix of a commit, or as an entry in the footer.
1243
+
1244
+ If included as a footer, a breaking change **MUST** consist of the uppercase text **`BREAKING CHANGE`**, followed by a colon, space, and description:
1245
+
1246
+ ```
1247
+ feat: allow provided config object to extend other configs
1248
+
1249
+ BREAKING CHANGE: `extends` key in config file is now used for extending other config files
1250
+ ```
1251
+
1252
+ If included in the `type/scope` prefix, breaking changes **MUST** be indicated by a **`!`** immediately before the **`:`**. If **`!`** is used, **`BREAKING CHANGE:`** **MAY** be omitted from the footer section, and the commit description **SHALL** be used to describe the breaking change:
1253
+
1254
+ ```
1255
+ feat!: send an email to the customer when a product is shipped
1256
+ ```
1257
+
1258
+ <!-- START mdsplit-ignore -->
1259
+ **[Return to Index](#conventional-commits-index)**
1260
+ <!-- END mdsplit-ignore -->