This section describes some of the coding standards that are being used in the pmp-library source tree. Although these standards should never be regarded as strict requirements they are still important to establish a minimum level of consistency through the code base as well as to facilitate code comprehension for developers and library users. Therefore, if you would like to contribute code to the pmp-library please make sure your code adheres to the conventions outlined below.

Naming

Types

The names of user-defined types such as classes, structs and enums use CamelCase notation. The names of persons such as Cholesky or Delaunay are properly capitalized as well.

Comments

Use C++-style comments, i.e., // my comment.

Doxygen Documentation Comments

We use Doxygen to generate our API documentation. All public types and interfaces should be properly documented. This usually includes a short abstract not longer than a sentence as well as a more detailed discussion of what the function does. We use //! for doxygen comments. The following is an example what a full documentation comment could look like:

Another good practice is to document pre- and post-conditions for performing an operation. Those can be documented using the \pre and \post Doxygen special commands.

Use Doxygen comments only in the header file. Do not repeat the same information in the implementation file. Instead, provide specific details on the implementation at hand, i.e., how was the functionality implemented, and why was it implemented in this manner?

Include Guards

Use the #pragma once compiler directive at the beginning of each header file in order to protect against multiple inclusion. Although this is not officially part of the language this feature is supported by all major compilers and is much more convenient than conventional header guards.

Namespace

Use the pmp namespace in order to avoid conflicts. In source files, do not add an additional level of indentation due to the namespace:

Type Consistency

Try to avoid conversion issues by using consistent types, e.g., use std::size_t when storing values from STL functions such as the size() member function of a std::vector. Use the C++11 auto keyword to let the compiler determine the proper types.

Structs vs. Classes

Use plain structs for data objectes providing nothing but a collection of other data types, e.g., a collection of parameters passed to a functions. Such a struct should not contain any further functionality than what is required for construction, destruction, or initialization. In contrast to class member variables, struct members do not have a underscore _ suffix.

Scoping

Localize variable scope and avoid declaring all variables at the beginning of a function or code block.

Using clang-format

Please use the clang-format tool and the corresponding .clang-format configuration file from the repository to properly format your code. We also provide a convenience CMake target to run clang-format on all source files:

$ make clang-format

This requires that the clang-format executable is found during CMake configuration. The exact path to the executable can be specified using

$ cmake -DCLANG_FORMAT_EXE=<path/to/executable> ..

Look for a line like this

-- clang-format found: /usr/bin/clang-format

in the CMake configuration output.

In case you want to preserve the special formatting of a particular code block such as a matrix intialization add the // clang-format off and // clang-format on directives around this block: