To unify code style, here are rules followed by this project:
- Each namespace should have it's own directory in Include and Source if .cpp files are present. Only exception for single-file utility namespace.
- Nested namespaces should have it's equivalent in directory structure.
- Before including headers in .cpp files check if it's already present in
Include/pch.h
since headers there are automatically added to every source file. - Name convetions:
- PascalCase:
- Namespaces
- Classes
- Structs
- Enums
- Methods
- Typedefs
- Template parameter types
- camelCase:
- Function variables and parameters
- Class fields
- ALL_CAPS:
- Macros
- Constexpr variables
- Template parameter variables
- Macros defined in header files in Common and Engine projects should be preceeded with ZE_.
- All switch macros disabling parts of code should be preceeded with ZE and have it's value defined for useage in conditional statements (0 or 1).
- PascalCase:
- References and pointers should be formatted without space,
SomeType* ptr;
,OtherType& ref;
- Avoid short names, let every function describe itself but don't make them too long.
- Don't use build in types, prefer usage of typedefs in Types.h, for ex. instead of
int
useS32
, etc. - Use
constexpr
whereever possible. - Instead of global variables in namespace, prefer utility classes with static methods.
- If function does not throw mark it as
noexcept
ornoexcept(ZE_NO_DEBUG)
if only contains debug exceptions. - Order of include files:
- Project headers
- External project headers
- Standard headers
- C library standard headers (preceeded with c)
- System headers and other ending with .h
- In source file first included header must be the same as source file name (or other header that included this file, in this case including said header can be ommitted).
- Classes and interfaces:
- Every class should have explicit:
- Destructor declaration, even if it's only
~SomeType() = default
. It helps not forgetting about virtual destructors. - Declaration of copy constructor and copy assignment operator, even if they are marked as default (or delete).
- Declaration of move constructor and move assignment operator, even if they are marked as default (or delete).
- Default (or delete) constructor declaration if no user specified one is present.
- Order of said methods:
- Default constructor (if present)
- User defined constructors (if present)
- Copy constructor
- Move constructor
- Copy assignment operator
- Move assignment operator
- Destructor
- If it's utility class with deleted constructor other said methods and destructor are not required.
- If it's interface class without variables then only destructor suficies.
- Destructor declaration, even if it's only
- Order of class content declaration:
private
friend classes declarationspublic
definitions of nested enums and classesprotected
definitions of nested enums and classesprivate
- Nested enums and classes
static constexpr
membersstatic
data members- Normal data members
- Methods
- Constructor as defined before
protected
definitions with same order asprivate
sectionpublic
definitions with same order asprivate
section
- If some methods have to be defined in header file they should follow after class declaration inside
#pragma region Functions
block. - Order of methods:
static constexpr
templated fully defined methodsstatic
templated inline defined methodsstatic constexpr
fully defined methodsstatic
inline defined methodsstatic constexpr
templated methods defined laterstatic
templated methods defined laterstatic constexpr
methods defined laterstatic
methods defined laterconstexpr
templated fully defined methods- Templated inline defined methods
constexpr
fully defined methods- Inline defined methods
constexpr
templated methods defined later- Templated methods defined later
constexpr
methods defined later- Methods defined later
- Every class that can be inherited from should have virtual destructor, exception only for class without base class and marked as
final
. - Interfaces should be named like
ISomeInterface
if possible. - Every interface should have explicit default virtual destructor.
- Every class should have explicit:
- While using
{}
place braces in new lines. switch()
should have its cases in same tabulation, and every case should have following{}
withbreak;
inside of them.