You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
oc-token = open close token such as parenthesis [,], (,), {,} and <,>
prefix tag = all characters before an oc-token
operator = math operator symbols like +, -, / ...
regex = regular expression to indicate where spaces must be placed
{...} = optional definition of ...
[:...:] = explicit placement of ...
1. Files and Encoding
files must be encoded in ASCII
LF ( line feed, \n , 0x0A ) must be used for new lines
each file must contain
copyright notice
the corresponding license header, author(s) + current year ( if changed - and a commit of a file means a change )
you never remove an author or a year, you only add to them
a #pragma once as guard to prevent double includes ( do not use #ifdef guards ) in header files
doxygen @file ... documentation directly after the license header and before the #pragma once
includes:
order from the most specific/specialized to the most general one
objects used from an include can be added in a comment but should at most be used for stable third party includes (can be used for includes from C++ STL, Boost, ...)
two empty newlines between the last include and the start of the code, one around #pragma once
/* Copyright 2017 Max Mustermann * * <YourLicense header>*//** @file file.hpp * * This is optional but can be useful for important files that do not only * implement a single class which can get the full docstring for it. * keep this text in one block, otherwise Doxygen will split it with wrong * association with the next upcoming code or namespace.*/
#pragma once
#include"myproject/file.def"
#include"myproject/myTypes.hpp"
#include"myproject/unStableApiTraits.hpp"// is_const<>, is_trait<> -> this should be avoided
#include<boost/mpl/vector.hpp>
#include<boost/type_traits.hpp>// is_void<>, is_union<>
#include<memory>// shared_ptrnamespacemyProject
{
/* ...*/
} // namespacee myProject
2. Project
each project must have a global namespace which covers all the code but not includes
the namespace structure
is equal to the folder structure
a file can have additional namespaces which are not represented by folders
the include folder contains as a first folder the project name e.g., include/picongpu, include/haseongpu
folder names must be written in camel case and begin with a lower case letter
the project name must begin with but can be fully composed of lower case letters (for folders and namespaces);
since this is a simplifcation for coding, the official spelling might differ
3. Global Rules
wrap a line after column 80
no TABS, use four (4) spaces per indentation level
no code alignment (only indentation)
names are always written in camel case syntax e.g., ThisIsCamelCase, thisIsAlsoCamelCase ( except: macros and defines )
if there is no content between { }, < >, [ ] or ( )
the oc-token token must be on the same line
one space between both oc-tokens ( regex: <[:space:]> )
oc-token{ }
{ is always placed on a new line ( same indentation level as the line before ) and followed by a new line
} is always placed on the same indentation level as the opening token
oc-token( )
for function / method signatures
( is placed after a prefix tag without a space before e.g., method( );
( must be followed by a new line ( except: if ( ) empty )
) is always placed on the same indentation level as the opening token ( except: if ( ) is empty )
for expressions e.g., ( a + 1 ) * 5;
can be placed on one line
after 80 characters a new line must follow
after first new line start indentation, see section Operators
for function calls e.g., foo( this );
for one function parameter use one line
for more than one function parameter place each indented on a new line, see section [Function Calls](cpp.md#9-Function Calls)
usage of end-of-line spaces is not allowed
it is not allowed to place a space before ;
semicolon ; is always followed by a new line, except in short (one-line) for statements
4. Comments
multiline comments
begin with /* ( or /** for doxygen) followed by a space ( regex: /*[:space:] )
end with */ on a new line
each line between begin and end starts with * ( regex: [:indentation:][:space:]*{[:space:]comment} )
single line comments begin with // (or //! for doxygen) followed by a space ( regex: //[::space:] )
it is not allowed to format comments with long symbol repetition e.g., // ################################
/*################################################# *# @brief block formating this is not allowed # *# # *# text text # *#################################################*/
doxygen inside comments is highly encouraged, see section doxygen
/* this is a multiline comment * where the end tag is on a new line*/// this is a single line comment
5. Doxygen Comments
oneline comments via //! should only be used when a brief title alone is descriptive enough (e.g. definition of a member variable)
for all other, multiline comments must be used for doxygen comments
brief ("title")
begins with /**
should be a single line comment
long description
is separated with an empty line
is not aligned with the brief line
use @ for doxygen commands e.g., @param, @return, @{
commands which should only rarely be used e.g., for code parts that are included from (license compatible!) third party projects (use the copyright header for full files or files that mainly consist of the external code)
@author
@date
@copyright
use @f[ / @f] or other formula commands to describe equations in latex
/** this is allowed * * text text*/
/** brief description * * long description is not aligned with brief line * @warning not thread save * @todo pass control arguments as enum * * @tparam T_Foo is our first template parameter * @param a is our first parameter * @param b is our second parameter * @return sum of input parameters*/template<
classT_Foo
>
HDINLINE staticintfunctionName(
T_Foo a,
double b
)
{
return0;
}
//! add fairy dustboolconst addMagic = true;
6. Namespaces
namespaces begin with a lower case letter
it is not allowed to indent nested namespaces
each namespace is defined on a separate line
the closing parenthesis } of a namespace must be placed on a new line together with a namespace name as comment
( regex: }[:space:]//[:space:]namespace[:space:]namespaceName$)
code inside the deepest namespace is indented
namespaceclair
{
namespacebob
{
namespacealice
{
// this one gets indentedstructFooMe;
} // namespace alice
} // namespace bob
} // namespace clair
7. Preprocessor
macros are written ALL_UPPERCASE and can use _
# is not indented
# is interpreted as one of the four (4) spaces for indentation
unary operators are placed directly before or behind the corresponding object e.g., i++, ++i and !enabled
binary operators
are surrounded by spaces e.g., x = a + b;
comma , ( d: in function signatures ) is always followed by a new line with same indent
operators except the comma operator do not require to be followed by a newline
after 80 characters a new line must follow
use the binary operator as the last code of the previous line
the first new line starts a new indentation block
voidmethod(
int & bob,
intconst & alice = 5
)
{
intbob( 10 );
intalice( 10 * bob );
bob = bob * alice + 12 * bob * bob * bob * bob++ * --alice +
bob -
alice;
alice = charge * charge / (
6.0 * PI * EPS0 * c2 * c2 * SPEED_OF_LIGHT * mass * mass
);
}
alternative tokens for operators && ( and ), | ( bitor ), ... are not allowed
9. Function Calls
for one function parameter
use one line e.g., method( 2 );
parameter is surrounded by spaces
for more than one function parameter place each indented on a new line
( ... ) are part of the caller (see above), no space to that caller
the type qualifier const is placed right hand of the type that shall be const (East Const)
note: constexpr is not a type qualifier, but an expression qualifier, write it left of the type!
& (reference), && (universal reference), and * (pointer) must be surrounded by one space
note: multi-level pointers are packed though
intconst * foo; // pointer to const int valueintconst * const foo; // const pointer to const int valueint * const foo; // const pointer to int valueint * foo; // pointer to int valueint ** foo; // pointer to a pointer to int valueint * const * foo; // pointer to a const pointer to int valueint* foo; // NOT ALLOWED by the coding guide lines (missing spaces around `*`)for( auto && e : vector ) // universal references are packed
{
}
constexprint i = 5; // this is a constant expression with ints
if possible use direct initialization over the assignment syntax
intfoo( 1 ); // should be preferred, if possibleint foo = 1; // should be avoided
for( int i = 0; i < 10; ++i )
{
// this is a simple loop
}
for(
std::vector<bool>::iterator it = v.begin();
it != v.end();
++it
)
{
// this is a loop with long type names in its parameters
}
while loop
while( i != endOfLoop )
{
// add your code here
}
while(
i != endOfLoop &&
d == 5
)
{
// add your code here
}
do while loop
do
{
// add your code here
}
while( i != endOfLoop );
15. Classes, Structs and Type Definitions
use camel case names that start with an upper case letter e.g., ClassBob, TypeNameBob
semicolon ;must be placed after the closing parenthesis }
code between { and };
access specifiers public, private and protected are not indented
all other code is indented
fixed prefix for each class is not allowed e.g., QApplication, QWidget (use namespaces)
inheritance
final specifier is placed inline with the class/struct name and surrounded by spaces
: is placed after the class name (regex: ClassName[:space:]:)
parent classes are indented and placed on a new line
each parent class is placed on a separate line
access specifiers public, private and protected and 'virtual' specifier must be placed inline with the parent class