• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
16This library is maintained by several developers, and in order it to have
17a consistent design, look and feel, a few guidelines need to be followed.
18
19Rules of [@boost:/development/requirements.html Boost Library Requirements and Guidelines]
20and [@boost:/development/header.html Boost Header Policy] always have highest authority.
21
22Generally, prefer style of modern C++, conventions as used in latest C++ standard
23document and C++ Standard Library. Boost.Spirit is a good example of
24how to write and format high quality C++ code.
25
26Some 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``
50namespace boost { namespace geometry
51{
52
53namespace mynewspace
54{
55
56template <typename Point>
57struct 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```
87struct 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```
102template
103<
104    typename T,
105    typename P,
106    typename C = std::vector<Point>
107>
108struct 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```
118T const& t;
119T* t;
120T* const t;
121T const* t;
122T const* const t;
123```
124* Braces enclosing block of code (if-else, loops) should be placed in separate lines
125```
126if (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```
150template <typename Range, typename Functor>
151static 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```
181namespace boost { namespace geometry
182{
183
184namespace detail { namespace foo
185{
186
187template <typename Point>
188struct 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
200namespace dispatch
201{
202
203template
204<
205    Geometry,
206    Tag = typename geometry::tag<Geometry>::type
207>
208struct foo
209{
210};
211
212// Specialization for POINT
213...
214
215} // namespace dispatch
216
217template <typename Point>
218inline 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]
233