CGAL 4.10 - Manual
|
We do not want to impose very strict coding rules on the developers. What is most important is to follow the CGAL naming scheme described in the next section. However, there are some programming conventions (Section Programming conventions ) that should be adhered to, rules for the code format (Section Code format ), and a mandatory heading for each source file (Section File header )
The CGAL naming scheme is intended to help the user use the library and the developer develop the library. The rules are simple and easy to remember. Where appropriate, they aim for similarity with the names used in the STL. Deviations from the given rules should be avoided; however, exceptions are possible if there are convincing reasons.
function_name
and Class_name
instead of functionName
or Classname
. Convex_hull_traits_2
for the name of the class that is a model of this concept. This different naming scheme for concepts and classes was adopted mainly for two reasons (a) it is consistent with the STL (cf. InputIterator) and (b) it avoids name clashes between concepts and classes that would require one or the other to have a rather contrived name. Triangulation
instead of Tri
). The only exceptions might be standard geometric abbreviations (such as "CH" for "convex
hull") and standard data structure abbreviations (such as "DS" for "data structure"). Unfortunately, the long names that result from the absence of abbreviations are known to cause problems with some compilers. ORIGIN
). Quotient
, Orientation
). is_zero
). is_empty
instead of simply empty
and has_on_bounded_side
instead of on_bounded_side
. Names of macros should begin with the prefix CGAL_
.
Vector_2
and Plane_3
). Exception: For \( d\)-dimensional objects there may be a dynamic and a static version. The former has the suffix _d
(e.g., Point_d
), while the latter has the dimension as the first template parameter (e.g., Point<d>
). Triangulation_2
, and a convex hull algorithm in 3-space is named convex_hull_3
. is_
or has_
, e.g. the data structure Min_ellipse_2
has member functions is_empty
and has_on_bounded_side
. vertices_begin
and vertices_end
return a Vertex_iterator
. (Note that we use the name of the items in singular for the iterator type name and in plural for the functions returning the iterator.) Names related to circulators are handled similarly, using the suffix _circulator
. For example, the function edges_circulator
returns an Edge_circulator
. All types in the kernel concept are functor types. We distinguish the following four categories:
orientation()
that return an enumeration type (values from a finite discrete set). As detailed below, the names of these functors reflect the actions performed by calls to operator()
. This naming scheme was chosen instead of one in which the computed object determines the name because this latter naming scheme is more natural for functions that compute values where the function call can be seen as a name for the object returned instead of functors that simply maintain data associated with the computation. It was also noted that the naming of functions and functors is not consistent, either in CGAL or in the STL (In some cases the action performed by a function determines its name (e.g., multiply()
) while in others the result of the action determines the name (e.g., product()
).), so achieving complete consistency with an existing naming scheme is not possible.
Here are the naming rules:
Orientation_2
object) the absence of the suffix would cause a name conflict with an existing type or class (e.g., the enumeration type Orientation
). Has_on_bounded_side_2
, Is_degenerate_2
, and Is_horizontal_2
. According to the current kernel we also have Left_turn_2
. For reasons of consistency with STL, all "less-than"-objects start with Less_
, e.g., Less_xy_2
. Further examples are Less_distance_to_point_2
and Less_distance_to_line_2
. However, we have Equal_2
, whereas the corresponding STL functor is called equal_to
. Here, we give our dimension rule higher priority. Construct_type_d
, where type_d
is the type constructed, e.g., Construct_point_2
and Construct_line_2
. The operator()
of these functor classes is overloaded. This reduces the number of names to remember drastically, while replacing one of the constructions gets more complicated, but is still possible. Functors in category 3 above can be further subdivided into two classes:
The names of functors in the first class also start with Construct_
whenever a geometric object is constructed, otherwise they start with Compute_
. Here, real numbers are not considered to be 1-dimensional geometric objects. For example, on the one hand we have Construct_perpendicular_vector_2
, Construct_midpoint_3
, Construct_circumcenter_d
, Construct_bisector_2
, and Construct_point_on_3
, while on the other hand there are Compute_area_2
and Compute_squared_length_3
.
For the second class, the names of the objects describe the (generic) action, e.g. Intersect_2
.
operator==()
) is replaced by function objects with names of the form Equal_k
, where k
is the dimension number (i.e., 2, 3, or d
). For replacing arithmetic operators, we might also provide Add_2
, Subtract_2
, Multiply_2
, and Divide_2
. (As mentioned above, the action determines the name, not the result.) We think that these objects are not really needed. They are likely to be part of primitive operations that have a corresponding function object in the traits. In addition, for each functor the kernel traits class has a member function that returns an instance of this functor. The name of this function should be the (uncapitalized) name of the functor followed by the suffix _object
.For example, the function that returns an instance of the Less_xy_2
functor is called less_xy_2_object
.
Triangulation_2.h
contains the data structure Triangulation_2
. /internal/
as a directory higher up in their hierarchy. For example CGAL/internal/foo.h
or CGAL/Package/internal/predicates/my_pred.h
. The first list of items are meant as rules, i.e., you should follow them.
const
when a call by reference argument is not modified, e.g. int f( const A& a)
.const
to indicate that a member function does not modify the object to which it is applied, e.g., class A { int f( void) const; };
. This should also be done when it is only conceptually const
. This means that the member function f()
is c
onst as seen from the outside, but internally it may modify some data members that are declared m
utable. An example is the caching of results from expensive computations. For more information about conceptually c
onst functions and mutable data members see [7].static_cast<double>( i)
instead of (
double)i.This_is_an_example.h
should begin/end with result_type
member typedef. An example for this is a C++03 style identity
functor: The following items can be seen as recommendations in contrast to the rules of previous paragraph.
define
sparingly. typedef
. Point_3_
to Point_3
(in general, add an underscore as suffix). The reason for this convention is that SFINAE does not extend to access control before C++11 (meaning that the existence of a private type can break overloading for other classes). //
some comment. Each CGAL source file must start with a heading that allows for an easy identification of the file. The file header contains:
For example and demo programs, the inclusion of the copyright notice is not necessary as this will get in the way if the program is included in the documentation. However, these files should always contain the name of the file relative to the CGAL_HOME
directory (e.g., examples/Convex_hull_3/convex_hull_3.cpp
) so the file can be located when seen out of context (e.g., in the documentation or from the demos web page).
For the test-suite and the documentation source, these are not distributed at the moment, so there is no policy for now.
Here follows what this gives for a file under the GPL :
Here follows what this gives for a file under the LGPL :
Requirements:
const
where appropriate