Warning, /acts/docs/codeguide.md is written in an unsupported language. File is not indexed.
0001 # Code guidelines
0002
0003 The following guidelines must be followed by all new code. Existing code that does not yet follow should be adapted when possible.
0004 You might disagree with some guidelines, but in a large code base as this one consistency is more important than personal opinion.
0005 All guidelines have a short identifier label, e.g. N.1, for easier reference in discussions.
0006
0007 For cases and constructs not explicitly mentioned here, code should fall back to the [C++ Core Guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines).
0008
0009 ## ACTS-specific
0010
0011 ### A.indices: Always use enum values to access vector/matrix components
0012
0013 Always use the appropriate enum values to access components. This clearly states
0014 the semantic meaning and is easier to understand.
0015
0016 Example:
0017
0018 ```cpp
0019 // local surface coordinate vector
0020 Vector2 loc;
0021 loc[ePos0] = 2.0;
0022
0023 // space-time coordinate vector
0024 Vector4 pos4;
0025 pos4[ePos0] = 0.1;
0026 ...
0027 pos4[eTime] = 12.3;
0028
0029 // bound parameters vector
0030 BoundVector pars;
0031 pars[eBoundLoc0] = 1.2;
0032 ...
0033 pars[eBoundPhi] = std::numbers::pi;
0034 ...
0035 ```
0036
0037 **Do not** use plain numbers as this can lead to inconsistencies if the order
0038 changes. It reduces the readability and makes it harder to spot errors.
0039
0040 **Do not** use the `.{x,y,z,w}()` accessors available for small fixed-size
0041 vectors. While this should produce correct results in most cases, the accessor
0042 name does not always match the semantic meaning, e.g. for momentum vectors, and
0043 it only works for vectors but not for matrices. Always use the entries in
0044 `enum CoordinateIndices` for a consistent way of accessing both vectors and matrices.
0045
0046 ## Naming
0047
0048 ### N.1: Namespaces use CamelCase
0049
0050 Namespaces use CamelCase with an upper case initial.
0051
0052 Example:
0053
0054 ```cpp
0055 namespace Something {
0056 ...
0057 }
0058 ```
0059
0060 The only exception is the nested `detail` namespace with always uses the lower-case name. There is no particular strong reason but existing practice for this. The `detail` namespace must be never be the top-most namespace.
0061
0062 Example:
0063
0064 ```cpp
0065 namespace Foo {
0066 namespace detail {
0067 ...
0068 }
0069 }
0070 ```
0071
0072 ### N.2: Concrete types use CamelCase
0073
0074 All concrete types, i.e. classes, structs, enums, and typedefs for both fundamental and external types, use CamelCase with an upper case initial.
0075
0076 Example:
0077
0078 ```cpp
0079 class ComplicatedNamedClass;
0080 struct AnotherStruct;
0081 enum EnumType;
0082 using SemanticName = int32;
0083 ```
0084
0085 Prefer semantic names over descriptive names. This applies in particular to typedefs of external types or standard containers. Types are checked by the compiler, while semantic meaning is only checked by the user; optimize for the latter.
0086
0087 Example:
0088
0089 ```cpp
0090 // avoid: purely descriptive typename
0091 using ConstThingPtrVector = std::vector<const Thing*>;
0092 // prefer: semantic typename the describes the usage
0093 using InputThings = std::vector<const Thing*>;
0094 ```
0095
0096 Avoid abbreviations and prefer full names. If abbreviations must be used, only use upper case for the initial letter of the abbreviation. The abbreviation is semantically a single word and this provides better visual consistency with the CamelCase naming.
0097
0098 Example:
0099
0100 ```cpp
0101 // VertexSomething should be abbreviated as
0102 struct VtxSomething; // not VTXSomething.
0103 // This is bad example since the name should not be abbreviated here anyway.
0104 ```
0105
0106 ### N.3: Functions and methods use mixedCase
0107
0108 All functions and methods use mixedCase with a lower case initial. This applies also to private helper functions, e.g. in the `detail` namespace. These are not fundamentally different from other functions and do not warrant a separate convention just by virtue of being e.g. in the `detail` namespace.
0109
0110 Example:
0111
0112 ```cpp
0113 doSomething(...);
0114 thing.doSomething(...);
0115 detail::anImplementationDetail(...);
0116 ```
0117
0118 ### N.4: Variables use mixedCase with appropriate prefix
0119
0120 Local variables, including function arguments, and public member variables use mixedCase with lower case initial.
0121
0122 Example:
0123
0124 ```cpp
0125 int aVariable;
0126 struct Thing {
0127 double aPublicVariable;
0128 float anotherPublicOne;
0129 };
0130 ```
0131
0132 Private member variables have an additional `m_` prefix.
0133
0134 Example:
0135
0136 ```cpp
0137 class Foo {
0138 private:
0139 m_privateMember;
0140 };
0141 ```
0142
0143 Static variables, i.e. local, global, and member ones, have an additional `s_` prefix to mark them as the satanic tools that they are.
0144
0145 ```cpp
0146 static int s_thisIsBadAndYouShouldFeelBad = -42;
0147 class Bar {
0148 static double s_notMuchBetter = 3.14;
0149 };
0150 ```
0151
0152 ### N.5: Constant values use kCamelCase
0153
0154 Variables representing constant values use CamelCase with a `k` prefix. Only variables marked as `constexpr` are considered constant values.
0155
0156 Example:
0157
0158 ```cpp
0159 static constexpr double kMagic = 1.23;
0160 ```
0161
0162 Variables defined in the `Acts::UnitConstants` namespace are exempted for usability reasons and use regular variable naming instead.
0163
0164 ### N.6: Enum values use eCamelCase
0165
0166 Enum values use CamelCase with a `e` prefix. They are not really constants but symbolic values, e.g. they can never have an address, and warant a separate convention.
0167
0168 Example:
0169
0170 ```cpp
0171 enum Bar {
0172 eBla,
0173 eBlub,
0174 };
0175 ```
0176
0177 ### N.7: Template parameter types use snake_case_t
0178
0179 Template parameter types use lower case words, separated by underscores, with a `_t` suffix. The separate naming convention from concrete types clarifies that these are variable types and avoids naming collisions when reexporting the type.
0180
0181 Example:
0182
0183 ```cpp
0184 template<typename large_vector_t>
0185 struct Algorithm {
0186 // make the template type publicly available
0187 using LargeVector = large_vector_t;
0188 ...
0189 };
0190 ```
0191
0192 ### N.8: Macros use ACTS_ALL_UPPER_CASE
0193
0194 Do not use macros. You want to use macros? Do not use them! Are you even listening? Ok, you are not: macros use `UPPER_CASE` with underscores as word separators and a mandatory `ACTS_` prefix.
0195
0196 Example:
0197
0198 ```
0199 #define ACTS_I_DID_NOT_LISTEN(...) ...
0200 ```
0201
0202 ### N.9: Files use CamelCase
0203
0204 Files use CamelCase with upper case initial. If the file defines a single class/struct, the filename must match the typename. Otherwise, a common name describing the shared intent should be used.
0205
0206 Source files use the `.cpp` extension, Header files use the `.hpp` extension, inline implementation files use the `.ipp` extensions.
0207
0208 Files that contain only symbols in the `detail` namespace should be moved in a`detail/` directory in the module directory. This should not be done for corresponding source files.
0209
0210 ## Formatting
0211
0212 See [](howto_format)