1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
# Contributing Guidelines
This document outlines the conventions to follow when contributing to this project.
## Commit Policy
### Run Tests Before Committing
Before preparing or proposing a commit, you **must** run the entire local test suite and ensure that all tests pass. This is a critical step to prevent regressions and maintain the stability of the codebase.
Refer to the "Testing" section in `HOWTO.md` for instructions on how to build and run the tests.
### Format Code Before Committing
All code **must** be formatted using `clang-format` before committing. This ensures a consistent coding style across the entire codebase.
To format your code, run the following command from the project root:
```bash
clang-format -i $(git ls-files | grep -E '\.(h|cc)$' | grep -vE '^(assets|archive|third_party)/')
```
Refer to the `.clang-format` file in the project root for the specific style rules.
### Ensure Newline at End of File
All source files (`.h`, `.cc`, `.cpp`, etc.) must end with a newline character. This prevents "No newline at end of file" errors from linters and ensures consistent file handling.
### Source File Headers
Every source file (`.h`, `.cc`) must begin with a concise 3-line comment header describing its purpose.
Example:
```cpp
// This file is part of the 64k demo project.
// It implements the core audio synthesis engine.
// This is not a user-facing header, but an internal one.
```
### Function and method comments
Functions and methods, especially if they are internal non user-facing,
should at least have a 1-line comment describing what they do or their
how/when they should be called. Except if they are just 1-line function
or very very short, obvious ones.
### '#endif' directive
The closing #endif directive must recall the corresponding opening #ifdef
clause they are closing
Example:
```cpp
#ifdef MY_TAG
...some code
#endif /* MY TAG */
```
We must also prefer '#if defined(MY_QUITE_LONG_TAG)' over '#ifdef MY_QUITE_LONG_TAG'
especially if there's a risk of having later something like:
```cpp
#if defined(MY_TAG_1) && !defined(MY_TAG_2)
```
### use and abuse 'const' directives
Especially for local variable, use 'const' qualification as much as
possible.
As an example, don't use:
```cpp
StructA variable_name = StructA(...);
```
but prefer instead:
```cpp
const StructA variable_name = StructA(...);
```
if variable_name is not mutated afterward.
Also: pass parameter as "const ref" as much as possible
(```const Struct& param``` instead of pointers or non-const refs)
### put spaces around code and operators (cosmetics)
Don't compact the code to much horizontally, and prefer adding extra
spaces around code and operators.
Example:
```cpp
const bool v = my_variable && (my_function() / 3. > (1. / x));
const y = function_call(3, x, 2.);
for (int x = 0; x < 24; ++x) { ... }
```
instead of
```cpp
const bool v=my_variable&&my_function()/3.>(1./x);
const y = function_call(3,x,2);
for(int x=0;x<24;++x){ ... }
```
### prefer prefixed incrementation over suffixed
Use pre-incrementation:
```cpp
++x
```
instead of post-incrementation:
```cpp
x++
```
### use extra () for boolean operations
Even if they are not strictly needed due to operator precedence rules,
prefer adding extra ()'s around tests for clarity, with parcimony.
### c++ cast
don't use reinterpret_cast<>, static_cast<> or const_cast<>.
### pointer declaration
prefer ```const T* name``` to ```const T *name```.
### 'auto' type
Don't use 'auto' as type, unless for complex iterators or very complex
types.
### don't use trailing spaces
don't.
|