forked from boostorg/geometry
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathguidelines.qbk
More file actions
232 lines (196 loc) · 7.74 KB
/
guidelines.qbk
File metadata and controls
232 lines (196 loc) · 7.74 KB
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
Copyright (c) 2009-2013 Mateusz Loskot, London, UK.
Use, modification and distribution is subject to the Boost Software License,
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================/]
[section:guidelines Guidelines for developers]
This library is maintained by several developers, and in order it to have
a consistent design, look and feel, a few guidelines need to be followed.
Rules of [@boost:/development/requirements.html Boost Library Requirements and Guidelines]
and [@boost:/development/header.html Boost Header Policy] always have highest authority.
Generally, prefer style of modern C++, conventions as used in latest C++ standard
document and C++ Standard Library. Boost.Spirit is a good example of
how to write and format high quality C++ code.
Some guidelines specific to Boost.Geometry library are outlined below.
[heading Code structure]
* Every file shall have header with copyright and license information.
* Do not put any history or revision information in comments in source files.
Log it with VCS used in the Boost project.
* Every header shall have `#include` guard based on header path and file name:
``
#ifndef BOOST_GEOMETRY_<DIR1>_<DIR2>_<FILE>_HPP
#define BOOST_GEOMETRY_<DIR1>_<DIR2>_<FILE>_HPP
...
#endif // BOOST_GEOMETRY_<DIR1>_<DIR2>_<FILE>_HPP
``
* `#include` directives shall be ordered according the most authoritative header:
* C Standard Library (using C++ library names, i.e. `<cstdlib>`)
* C++ Standard Library
* Boost C++ Libraries
* Boost.Geometry headers
* Other 3rd-party headers (only if applicable! in some samples only)
* Header within these sections should be ordered alphabetically, especially if there are many of them included.
* Namespaces don't increase the level of indentation.
In all other cases braces increase the level of indentation.
``
namespace boost { namespace geometry
{
namespace mynewspace
{
template <typename Point>
struct my_new_model
{
typedef point_type;
}
} // namespace mynewspace
}} // namespace boost::geometry
``
* Namespace closing brace should have comment with the namespace name.
* All non-public headers should be placed into `boost/geometry/detail` or
`boost/geometry/*/detail` directory, depending on component level.
* All non-public names should reside in the `boost::geometry::detail` or
`boost::geometry::*::detail` namespace, depending on component level.
* All traits should be placed in dedicated `boost::geometry::traits` or
`boost::geometry::*::traits` namespace
* All tag dispatching routines should be placed in dedicated
`boost::geometry::*::dispatch` namespace.
* Access specifiers for class members shall be orderd as public first, then protected and private at the bottom.
The public members define class interface, thus they are of the highest interested for users, so show them first.
* Exceptions to this rule are allowed for typedef aliases required to be defined first.
[heading Code formatting and indentation]
* The code is indented with spaces, 4 spaces per tab.
* The preferred line length is 80 characters, with maximum length of 100.
* The limit is relaxed for very long string literals (e.g. Well-Known Text with data used in tests and examples).
* Member/base initialization list for constructors on the same line,
if it's small (1-2 members) or 1 member/base per line with leading comma on the left:
```
struct T
{
T(int a, int b)
: a(a)
, b(b)
{}
int a;
int b;
};
```
* Template declaration with long template parameter list shall be formatted
with one template parameter per line, all parameters indented,
but `<` and `>` brackets not indented:
```
template
<
typename T,
typename P,
typename C = std::vector<Point>
>
struct polygon
{
typedef typename boost::remove_const
<
typename traits::point_type<T>::type
>::type type
};
```
* References and pointers should be formatted emphasizing type, not syntax:
```
T const& t;
T* t;
T* const t;
T const* t;
T const* const t;
```
* Braces enclosing block of code (if-else, loops) should be placed in separate lines
```
if (expr)
{
}
```
* Parentheses around expressions should not be pre/post-fixed with spaces.
[heading Naming conventions]
* All names follow style of the C++ Standard, lowercase with words separated with underscore `_`,
unless otherwise specified (see other rules).
* Template parameters are named in CamelCase.
* Concepts are named in CamelCase.
* Name of a class data member shall start with `m_` prefix.
The Boost sample header gives no prefix or suffix at all.
However, the `m_` prefix is used in some (not many) Boost libraries as well (e.g. math/tools/remez).
* All macro names shall be in upper-case, words separated with underscore `_`.
* All macro names shall start with `BOOST_GEOMETRY_`.
* All non-public macro names should start with `BOOST_GEOMETRY_DETAIL_` (not used often yet, if at all).
* All public names should reside in the `boost::geometry` namespace.
Nested namespaces are also possible.
* Avoid cryptic names and abbreviations for elements used in wider context (e.g. types, functions).
Short names are allowed if context of use is local, narrow and easily tracable
For example, use of `it` for `iterator` in body of a loop in function:
```
template <typename Range, typename Functor>
static inline void apply(Range& range, Functor& f)
{
for (typename boost::range_iterator<Range>::type it = boost::begin(range);
it != boost::end(range); ++it)
{
f(*it);
}
}
```
[heading C++ use conventions]
* Keyword struct is preferred either for POD structures, or for classes used at compile-time
like metafunctions, tags, traits, etc.
* Keyword class is preferred for classes meant to produce actual objects, which have methods
and an active role in the runtime functioning of the program.
* In case of a template, prefer use of typename keyword over class.
[heading Specialisations and dispatching conventions]
* Algorithms are free inline functions, taking any geometry. Parameters are often one or two geometries
* There might be an overload for a strategy. The strategy takes, a.o. care of coordinate systems
* The free `inline` function forwards to a dispatch struct, specialized for the geometry type (so for point, polygon, etc.)
* They have an `static` (`inline`) function called apply
* The dispatch struct calls, or is derived from, an struct implemented in namespace detail
* There the same: a `struct` with a `static` (`inline`) function called apply
* This way the implementation structs are building blocks, they can be reused
* In fact they are reused often by the multi-versions of the algorithms
```
namespace boost { namespace geometry
{
namespace detail { namespace foo
{
template <typename Point>
struct foo_point
{
// template parameters here
static inline int apply(Point const& p)
{
// do something here
return 1;
}
};
}} // namespace detail::foo
namespace dispatch
{
template
<
Geometry,
Tag = typename geometry::tag<Geometry>::type
>
struct foo
{
};
// Specialization for POINT
...
} // namespace dispatch
template <typename Point>
inline int foo(Point const& point)
{
return dispatch<Point>::apply(point);
}
}} // namespace boost::geometry
```
[heading Contributing code]
* Create a patch, open a ticket in the Boost Trac with your patch attached.
* Alternatively, post your patch to the Boost.Geometry mailing list.
* If you contribute a code, always try to provide a minimal test for it.
[endsect]