Commit 3a77d2f7 authored by Dominik Charousset's avatar Dominik Charousset

Reorganize HACKING guide

parent 8a03aad0
......@@ -2,11 +2,12 @@ This document specifies the coding style for the C++ Actor Framework.
The style is based on the
[Google C++ Style Guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml).
# Example for the Impatient
#### `libcaf_example/caf/example/my_class.hpp`
Example for the Impatient
=========================
```cpp
// libcaf_example/caf/example/my_class.hpp
#ifndef CAF_EXAMPLE_MY_CLASS_HPP
#define CAF_EXAMPLE_MY_CLASS_HPP
......@@ -66,9 +67,9 @@ class my_class {
#endif // CAF_EXAMPLE_MY_CLASS_HPP
```
#### `libcaf_example/src/my_class.cpp`
```cpp
// libcaf_example/src/my_class.cpp
#include "caf/example/my_class.hpp"
#include <iostream>
......@@ -112,33 +113,47 @@ void my_class::do_something() {
```
# General rules
General rules
=============
- Use 2 spaces per indentation level.
- The maximum number of characters per line is 80.
- Never use tabs.
- Vertical whitespaces separate functions and are not used inside functions:
use comments to document logical blocks.
- Header filenames end in `.hpp`, implementation files end in `.cpp`.
- Member variables use the prefix `m_`.
- Thread-local variables use the prefix `t_`.
- Never declare more than one variable per line.
- `*` and `&` bind to the *type*.
- Class names, constants, and function names are all-lowercase with underscores.
- Template parameter names use CamelCase.
- `*` and `&` bind to the *type*, e.g., `const std::string& arg`.
- Namespaces do not increase the indentation level.
- Access modifiers, e.g. `public`, are indented one space.
- Use the order `public`, `protected`, and then `private`.
- Always use `auto` to declare a variable unless you cannot initialize it
immediately or if you actually want a type conversion. In the latter case,
provide a comment why this conversion is necessary.
- Never use unwrapped, manual resource management such as `new` and `delete`.
- Do not use `typedef`. The syntax provided by `using` is much cleaner.
- Use `typename` only when referring to dependent names.
- Keywords are always followed by a whitespace: `if (...)`, `template <...>`,
`while (...)`, etc.
- Always use `{}` for bodies of control structures such as `if` or `while`,
even for bodies consiting only of a single statement.
- Opening braces belong to the same line:
```cpp
......@@ -148,6 +163,7 @@ void my_class::do_something() {
my_other_fun();
}
```
- Use standard order for readability: C standard libraries, C++ standard
libraries, other libraries, (your) CAF headers:
```cpp
......@@ -161,26 +177,76 @@ void my_class::do_something() {
#include "caf/example/myclass.hpp"
```
# Headers
- When declaring a function, the order of parameters is: inputs, then outputs.
- Never use C-style casts.
Naming
======
- Class names, constants, and function names are all-lowercase with underscores.
- Types and variables should be nouns, while functions performing an action
should be "command" verbs. Classes used to implement metaprogramming
functions also should use verbs, e.g., `remove_const`.
- Member variables use the prefix `m_`.
- Thread-local variables use the prefix `t_`.
- Static, non-const variables are declared in the anonymous namespace
and use the prefix `s_`.
- Template parameter names use CamelCase.
- Getter and setter use the name of the member without the `m_` prefix:
```cpp
class some_fun {
public:
// ...
int value() const {
return m_value;
}
void value(int new_value) {
m_value = new_value;
}
private:
int m_value;
};
```
Headers
=======
- Each `.cpp` file has an associated `.hpp` file.
Exceptions to this rule are unit tests and `main.cpp` files.
- Each class has its own pair of header and implementation
files and the relative path is derived from its full name.
For example, the header file for `caf::example::my_class` of `libcaf_example`
is located at `libcaf_example/caf/example/my_class.hpp`.
Source files simply belong to the `src` folder of the component, e.g.,
`libcaf_example/src/my_class.cpp`.
- All header files should use `#define` guards to prevent multiple inclusion.
The symbol name is `<RELATIVE>_<PATH>_<TO>_<FILE>_HPP`.
- Do not `#include` when a forward declaration suffices.
- Each library component must provide a `fwd.hpp` header providing forward
declartations for all types used in the user API.
- Each library component must provide an `all.hpp` header including
all headers for the user API and the main page for the documentation.
- Each library component must provide an `all.hpp` header that contains
main page for the documentation and includes all headers for the user API.
- Use `inline` for small functions (rule of thumb: 10 lines or less).
## Template Metaprogramming
Template Metaprogramming
========================
Despite its power, template metaprogramming came to the language pretty
much by accident. Templates were never meant to be used for compile-time
......@@ -191,9 +257,11 @@ extra rules for formatting metaprogramming code.
- Brake `using name = ...` statements always directly after `=` if it
does not fit in one line.
- Consider the *semantics* of a metaprogramming function. For example,
`std::conditional` is an if-then-else construct. Hence, place the if-clause
on its own line and do the same for the two cases.
- Use one level of indentation per "open" template and place the closing `>`,
`>::type` or `>::value` on its own line. For example:
```cpp
......@@ -212,28 +280,29 @@ extra rules for formatting metaprogramming code.
else (optional<result_type>)
};
```
- Note that this is not necessary when simply defining a type alias.
When dealing with "ordinary" templates, indenting based on the position of
the opening `<` is ok too, e.g.:
the opening `<` is ok, e.g.:
```cpp
using response_handle_type = response_handle<Subtype, message,
ResponseHandleTag>;
```
# Miscellaneous
## Rvalue references
Rvalue references
=================
- Use rvalue references whenever it makes sense.
- Write move constructors and assignment operators if possible.
## Casting
- Write move constructors and assignment operators if possible.
- Never use C-style casts.
## Preprocessor Macros
Preprocessor Macros
===================
- Use macros if and only if you can't get the same result by using inline
functions or proper constants.
- Macro names use the form `CAF_<COMPONENT>_<NAME>`.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment