1.. _Coding Style:
2
3Coding Style (C++)
4==================
5
6This is an overview of the coding conventions we use when writing C++
7code for the Open Chemistry projects. The style is based largely on the
8`Qt <https://wiki.qt.io/Qt_Coding_Style>`__ and
9`KDE <https://community.kde.org/Policies/Library_Code_Policy>`__ styles.
10
11Code formatting is enforced through use of the clang-format tool.
12
13Indentation
14^^^^^^^^^^^^
15
16-  2 spaces are used for indentation
17-  Spaces, not tabs!
18
19.. _line_width:
20
21Line Width
22^^^^^^^^^^^^
23
24-  Keep lines of source code to less than 80 characters wide.
25
26.. _declaring_variables:
27
28Declaring Variables
29^^^^^^^^^^^^^^^^^^^^
30
31-  Declare each variable on a separate line
32-  Avoid abbreviations (e.g. "a", "nmbr") where possible
33-  Single character variable names are fine for counters, temporary
34   variables etc where the purpose is obvious
35-  Wait until a variable is needed to declare it, don't keep unused ones
36   around
37
38.. code:: cpp
39
40     // Incorrect
41     int nmbr, f;
42
43     // Correct
44     int number;
45     int result;
46
47-  Variables and function names start with a lower case letter, with
48   other words using camel case
49-  Abbreviated names should be avoided
50-  Acronyms are camel-cased (e.g. CmlFormat, not CMLFormat)
51
52.. code:: cpp
53
54     // Incorrect
55     double Cntr;
56     std::string rawXML;
57     char LIST_DELIMITER = '\t';
58
59     // Correct
60     double center;
61     std::string rawXml;
62     char listDelimiter = '\t';
63
64-  Class names always start with an upper-case letter
65-  Public classes should be placed inside the appropriate namespace
66-  Member variables should start with m\_
67
68Whitespace
69^^^^^^^^^^
70
71-  Use blank lines to group statements together where appropriate
72-  Only use a single blank line
73-  Always use a single space after a keyword and before a curly brace
74
75.. code:: cpp
76
77   // Wrong
78   if(blah){
79     explode();
80     return 5;
81   }
82
83   // Correct
84   if (blah) {
85     explode();
86     return 5;
87   }
88
89-  For pointers or references, always use a single space between the
90   type and the '*' or '&', but no space between that character and the
91   variable name.
92
93.. code:: cpp
94
95     char *x;
96     const std::string &myString;
97     const char * const y = "whoah";
98
99-  Surround binary operators with spaces
100-  No space after a cast
101-  Avoid the use of C-style casts
102
103.. code:: cpp
104
105     // Incorrect
106     char* memoryBlock = (char*) malloc(data.size());
107     // Correct
108     char *memoryBlock = reinterpret_cast<char *>(malloc(data.size()));
109
110Braces
111^^^^^^^
112
113-  The left curly brace normally goes on the same line as the start of
114   the statement
115
116.. code:: cpp
117
118     //Incorrect
119     if (foo)
120     {
121       run();
122       break;
123     }
124
125     // Correct
126     if (foo) {
127       run();
128       break;
129     }
130
131-  Exception: if this is class declarations and function
132   implementations. The left brace always goes on the start of a line
133   there
134
135.. code:: cpp
136
137     void myFun(const std::string &name)
138     {
139       std::cout << "Supplied name: " << name << std::endl;
140     }
141
142     class Bar
143     {
144     public:
145       Bar();
146     };
147
148-  Use curly braces when the body of a conditional contains more than
149   one line, and also if a single statement is complex
150
151.. code:: cpp
152
153     // Incorrect
154     if (!correct) {
155       return false;
156     }
157
158     for (int i = 0; i < 42; ++i) {
159       var += i;
160     }
161
162     // Correct
163     if (!correct)
164       return false;
165
166     for (int i = 0; i < 42; ++i)
167       var += i;
168
169-  Exception: Use curly braces if the parent statement does not fit on
170   one line/wraps
171
172.. code:: cpp
173
174     // Correct
175     if (!correct || !isValid
176         || !aGoodDay) {
177       return false;
178     }
179
180-  Exception: Use curly braces in any if, then, else blocks where any of
181   the elements cover several lines
182
183.. code:: cpp
184
185     // Incorrect
186     if (!correct)
187       return false;
188     else {
189       ++counter;
190       return true;
191     }
192
193     // Correct
194     if (!correct) {
195       return false;
196     }
197     else {
198       ++counter;
199       return true;
200     }
201
202     // Incorrect
203     if (a)
204       if (b)
205         return true;
206       else
207         return false;
208
209     // Correct
210     if (a) {
211       if (b)
212         return true;
213       else
214         return false;
215     }
216
217-  Use curly braces when the body is empty.
218
219.. code:: cpp
220
221     // Incorrect
222     while (true);
223
224     // Correct
225     while (true) {}
226
227Parentheses
228^^^^^^^^^^^^
229
230-  Parentheses should be used to group expressions, and to make the
231   intent clearer
232
233.. code:: cpp
234
235     // Incorrect
236     if (a && b || c)
237
238     // Correct
239     if ((a && b) || c)
240
241     // Incorrect
242     x = a + b & c;
243
244     // Correct
245     x = (a + b) & c;
246
247.. _switch_statements:
248
249Switch Statements
250^^^^^^^^^^^^^^^^^^
251
252-  The case labels should be in the same column as the switch
253-  Every case must have a break/return statement at the end, or a
254   comment to indicate the omission
255-  Exception: Another case follows immediately
256
257.. code:: cpp
258
259     switch (myEnum) {
260     case LINE:
261       drawLine();
262       break;
263     case POINT:
264     case VERTEX:
265       drawDot();
266     // Fall through to default.
267     default:
268       drawDefault();
269       break;
270     }
271
272.. _line_breaks:
273
274Line Breaks
275^^^^^^^^^^^^
276
277-  Keep lines shorter than 80 characters; insert breaks if necessary
278-  Commas go at the end of a broken line
279-  Operators go at the beginning of a new line
280
281.. code:: cpp
282
283     // Correct
284     if (veryLongExpression()
285         && anotherEvenLongerExpression()
286         && justWhenYouThoughtItCouldntGetLonger()) {
287       doSomething();
288     }
289     Eigen::Vector3d position(currentPosition.x() + offset,
290                              currentPosition.y() + offset,
291                              0);
292
293.. _inheritance_and_the_virtual_keyword:
294
295Inheritance and the "virtual" Keyword
296^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
297
298-  When reimplementing a virtual method, do not put the "virtual"
299   keyword in the header
300
301.. _referencing_members:
302
303Referencing Members
304^^^^^^^^^^^^^^^^^^^^
305
306-  The use of this-> is discouraged. The use of the m\_ prefix should
307   make it clear that a member variable is being referenced.
308
309.. _file_naming:
310
311File Naming
312^^^^^^^^^^^^
313
314-  All file names should be lower-case.
315-  C++ source files should have a .cpp extension.
316-  C++ header files should have a .h extension.
317
318.. _general_exception:
319
320Breaking Rules
321^^^^^^^^^^^^^^^^^
322
323-  As with Qt, and others, feel free to break a rule if it makes your
324   code look bad!
325