- C++14/17
- CMake
- Enable all possible warnings (
-Wall
,-Werror
), ASAN and UBSAN (if possible)
Library | Description | For | License |
---|---|---|---|
CPM | CMake Package Manager | CMake | MIT |
expected | std::expected implementation |
C++ < 23 | CC0 |
span | std::span implementation |
C++ < 20 | BSL 1.0 |
fmtlib | Modern String Formatting | C++ >= 11 | MIT |
scnlib | Modern "scanf" implementation | C++ >= 11 | Apache 2.0 |
spdlog | Logging | C++ >= 11 | MIT |
json | JSON for Modern C++ | C++ >= 11 | MIT |
doctest | Unit Testing Framework | C++ >= 11 | MIT |
LevelDB | Key => Value Storage | C++ | BSD 3-Clause |
RE2 | Regex Engine | C++ | BSD 3-Clause |
snake_case
for methods,CamelCase
for types and template arguments- Types must be prefixed with the project-id (eg. proj_mytype)
- Setter functions are like
set_value(int)
but getters don’t have any prefix (eg.int value()
) - Define member functions first, then member variables. Public members before non-public (in that order)
- Class data members start with a leading
m_
and static data members with a leadings_
- Attach
*
and&
to type names, not variables - Use
using
statement instead oftypedef
Order of includes
#include "my_class.hpp" // corresponding to my_class.cpp
#include <vector> // C++ Standard libraries
#include <fmt/core.h> // Headers from dependencies outside project
#include "my_project.h" // Headers from current project
- Prefer
#pragma once
for headers static_assert
statement- Minimize usage of
auto
keyword - Copy constructor and assignment operator are to be deleted (move constructor/assignment allowed)
- All constructors must be marked
explicit
- If one special member function is defined, then all the remaining must also be defined (either
= default
or= delete
) - Prefer
std::array
instead ofstd::vector
if you need a fixed storage - Use
typedef struct X { } X;
statement if C support is needed - Raw-pointers for non-owned pointers
- Smart-Pointers for owned pointers
- Prefer freestanding functions declared in .cpp file wrapped in an anonymous namespaces instead of private functions
- Use Uniform initialization
const_cast
is designed to be only used with legacy APIs that are not const correct- Minimize usage of
reinterpret_cast
- References instead of pointers (references cannot be
nullptr
) - Pointers ONLY FOR optional arguments
[[nodiscard]]
attributeenum class
instead ofenum
constexpr
statements- Minimum RAII
- Namespaces
- C Headers,
malloc
andfree
(use c-prefixed headers instead, eg.stdint.h
->cstdint
) - Class declarations (prefer structs)
- Constructors and Destructors if error reporting is needed (eg.
init
anddeinit
) - Private fields
- Structs must be "Plain Old Data" (POD)
- Virtual methods
- Complex function overloadings (allowed only for first argument, otherwise prefer default values)
- Complex templates
- Macros (prefer static inline functions)
std::function
: Use a template instead (it does't prevent inlining) or a function pointer.new
anddelete statements
- Global Variables
- Owned Raw pointers (but they are acceptable if managed and handled inside a struct)
- Exceptions
- C style casts (use
static_cast
) using namespace
statement (prefernamespace nsalias = my::nspace
in .cpp files)- Multiple Inheritance
- Non-Public Inheritance
- Complex class/struct relations
- Virtual function calls in constructors
- Virtual Inheritance
- Helper objects
- Friend
- SFINAE
- RTTI
- Containers
- All STL containers are allowed.
- Prefer
<vector>
for any container type if ABI compatibility is needed - Avoid iterators if you are using C++17
- General
- Avoid:
<iostream>
,<sstream>
- Avoid: