-
Notifications
You must be signed in to change notification settings - Fork 9
/
style-guidelines.txt
119 lines (94 loc) · 3.17 KB
/
style-guidelines.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
* Code style guidelines by example (or see .clang-format for an approximation
* of how to automate part of this)
*/
/*
* Do not use "typedef", always use "using". The "using" construct actually gets
* the order sane. Make type aliases whenever it seems useful. Do not hold back,
* especially if the type is long or *could ever change*.
*/
using NodeType = uint16_t;
struct OtherClass {
virtual void myTestMethod(int a) = 0;
};
// Prefer "struct" over "class"
template <typename T, typename U = void>
struct MyClassName : OtherClass {
using MyIntType = int32_t;
using IteratorType = typename std::vector<MyIntType>::const_reverse_iterator;
// Use defaults when possible and needed
MyClassName() = default;
MyClassName(MyClassName&&) = default;
MyClassName(MyClassName const&) = default;
// Often your destructor should be virtual
virtual ~MyClassName() = default;
// if it is above 80 cols, wrap to next line with regular indenting
static inline typename Abc<T,X>::type mySimpleMethod(
int a, int b, int c, int d
);
// Use the override keyword, it can only help you
void myTestMethod(int a) override {
// Initialize stack variables as much as possible (and static when possible)
int a = 0, tmp = 0;
int my_local_count = 0;
std::vector<int> my_vec = {};
/*
* Don't be afraid to use "and" or "or" or "not_eq". Often it's more
* readable. It's fully C++ standard compliant.
*/
if (my_local_count != 0 and a == 0) {
a = 10;
}
// Braces instead of semicolon when empty
while (true) { }
// Prefer spacing here
for (int i = 0; i < 10; i++) {
}
for (auto&& elm : my_vec) { }
}
// if function returns bool, don't make the name too complicated
bool valid() const;
private:
// Private members have trailing underscore
int my_data_;
bool is_coll_; // if data is boolean, it should start with "is" or "has"
};
/*
* Wrap typename args when they get long, start ">" on next line, indented as
* so. Use "typename" unless you have to use "class": exception being template
* templates. Space goes here: "template <". Ellipses on on LHS for parameter
* packs
*/
template <
typename CollectionT, typename IndexT, typename TupleT, typename RetT,
typename... Args
>
struct ManyTemplateParams {
// Wrap function args when they get long, indented as so
RetT operator()(
CollectionT const& col, IndexT const& idx, TupleT&& tup,
std::tuple<Args...> tup, std::unique_ptr<intt64_t> ptr
) {
return {};
}
};
/*
* Use an enum struct when possible. Degrading automatically (happens with
* non-strongly typed enums) may introduce bugs
*/
enum struct CallbackEnum : int32_t {
ConstantOne = 0,
ConstantTwo = 1
};
// A new line should be after the template, even in cases like this:
template <typename T>
struct A;
// Use tag types when necessary. Name the type *Type explicitly, tag without
struct MyTagType { } MyTag { };
/*
* Do not indent code under a namespace. Always combine multiple nested
* namespaces in one line (makes it easier to identify the full namespace path)
* unless you need to wrap, then try to semantically group them
*/
namespace X { namespace Y {
}} // end namespace X::Y