Basis: C++ Core Guidelines
Exceptions:
- Use east-
constnotation (at variance with NL.26: Use conventional const notation) - It is permitted to use
constmember data when not all member functions can beconst-qualified (at variance with C.12: Don’t make data membersconstor references in a copyable or movable type). This can be especially important in guarding against multi-threading pitfalls. - It is permitted to use references as data members when (a) the class does not need to be copy-assignable, and (b) the data member must be non-null (at variance with C.12: Don’t make data members
constor references in a copyable or movable type)
We will use clang-format to adopt a unified style:
The namespace for C++ Phlex code is simply phlex, where two leading colons (i.e. ::phlex) may be used to disambiguate between the top-level namespace and any nested namespaces.
We adopt the underscore-style or snake-case naming convention, consistent with the following C++ core guidelines:
- NL.8: Use a consistent naming style
- NL.9: Use
ALL_CAPSfor macro names only - NL.10: Prefer
underscore_stylenames
The snake case convention will apply to variables, functions (free and member), classes, namespaces, files, and any C++ modules.
Note that the SCREAMING_SNAKE_CASE (or ALL_CAPS style) will be reserved for only macro names, consistent with the NL.9 C++ core guideline referenced above.
Exceptions to the snake-case rule include the names of:
- executables, which should prefer hyphens instead of underscores (e.g.
phlex-programis easier to type thanphlex_program) - template parameters, which should prefer Pascal case (see here for distinction between Camel and Pascal cases)
Functions should be verbs; classes should be nouns.
A symbol should have a trailing underscore always and only if it is private member data: neither public member data nor private member functions should have them (public data member are expected to only be access via their containing symbol name (mystruct.my_value or this->my_value in the rare case of member function of struct with public data member).
Functors (classes whose instances act like a function) should be an agent noun: the noun form of an action verb. Instances of a functor should be a verb. For example:
ModelEvaluator evaluate_something(parameters...);
auto result = evaluate_something(arguments...);Generally speaking, variables should have short lifetimes and should be self-documenting (see C++ core guidelines NL.1 and NL.7).
Avoid shorthand and “transliterated” mathematical expressions: prefer constants::n_avogadro to N_A (or express the constant functionally with atoms_per_mole) and use atomic_number instead of Z.
Physical constants should try to have the symbol concatenated to the context or meaning (e.g. c_light or h_planck).
Use scoped enumerations (enum class) where possible (named like classes) so their values can safely be named like member variables (lowercase with underscores) (see C++ core guideline Enum.3).
Prefer enumerations to boolean values in function interfaces (since do_something(true) requires looking up the function interface definition to understand (see C++ core guideline I.4).