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 +1246 -5
- package/README.md +181 -56
- package/ROADMAP.md +107 -0
- package/bin/client.wasm +0 -0
- package/bin/package.json +1 -1
- package/contributing/conventional-commits.md +3 -10
- package/contributing/documentation.md +3 -45
- package/contributing/formatting.md +4 -8
- package/contributing/style-guide.md +4 -60
- package/package.json +1 -1
- package/ARCHITECTURE.md +0 -3
- package/BUILD.md +0 -443
- package/docs/assets/app-icon.png +0 -0
- package/docs/calculators/fixture_heat_loss_calculator.dox +0 -29
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 -->
|