-
Notifications
You must be signed in to change notification settings - Fork 107
Coding Rules
#define SNAKE_CASE (1)
namespace snake_case {
// east const
constexpr char const snake_case = 0b00000010;
template <typename UpperCamelCase>
class snake_case {
public:
void snake_case() {
if (condition1) { // whitespace after if and between ) and {
// ...
}
else { // don't } else {
// ...
}
switch (condition2) {
case 1: // case indent level is same as switch
// ...
break;
case 2:
// ...
break;
case 3: {
int local_variable = 1;
// ...
} break;
}
// whitespace after for , & is connected with type not variable, whitespace before and after :
for (auto const& e : collection) {
}
}
template <typename SomethingLong>
std::enable_if_t< // std::enable_if_t is C++14 feature. Use it instead of typename std::enable_if<...>::type
std::is_same< // if the parameters are long, then use this type multi line indent.
SomethingLong,
int
>::value // std::is_same_v is C++17 feature. Don't use it.
>
multi_line_function_template(SomethingLong v) {
// ...
}
private:
int snake_case_; // underscore postfix
};
} // namespace snake_case
Indent is four spaces, please don't use TAB.
If condition has an else clause, condition should be positive. This rule is applied not only MACRO but also normal if-else
.
// OK
#if defined(SOME_CONDITION)
// do A
#else // defined(SOME_CONDITION)
// do B
#endif // defined(SOME_CONDITION)
// NG
#if !defined(SOME_CONDITION)
// do B
#else // !defined(SOME_CONDITION)
// do A
#endif // !defined(SOME_CONDITION)
Immediate invoking lambda expression is more preferred than conditional operator. If the types of return values are different, the lambda expression can declare the return type explicitly.
auto r =
[&]() -> int {
if (cond1 == 0) {
if (cond2 == 0) {
return 100;
}
return 200;
}
return 300;
} ();
Equivalent conditional operator. It is complicated.
int r = cond1 == 0 ? cond2 == 0 ? 100
: 200
: 300;
If the expression is simple enough, you can use conditional operator.
If the lambda expression has long capture list and/or long parameter list, write as follows:
auto lambda =
[.................](.................) {
};
// or
auto lambda =
[.................]
(.................) {
};
If the lambda expression is called in the function, then you can use [&]
capture.
void foo() {
auto lambda = [&] {};
// ...
lambda();
}
However, if the lambda expression is called after the function is finished, then you need to use explicit capture list. It is typical situation on asynchronous API callback.
void foo(int& i) {
auto lambda = [&i] {};
// ...
as::post(ioc, lambda);
}
Please respect the order.
- Basically use the value.
foo f;
. - If the value should be nullable, then use
MQTT_NS::optional
.MQTT_NS::optional<foo> f
. In order to lazy initalize, usef.emplace(...)
. - If there is convincible reason to locate the value to the heap, then use
std::unique_ptr<foo> f
. Don't usestd::shared_ptr<foo>
. - If and only if reference counting pattern is required, then use
std::shared_ptr<foo> f
.
- Requirements
- Config
- Tutorial
- Authentication and Authorization
- Advanced topics
- Examples
- API Reference
- Versioning Policy
- How to contribute