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