Developer/Guidelines

Version 1 (modified by mloskot, 4 years ago)

Migrated guidelines from development_notes.txt file to Wiki page

Development Guidelines

This document outlines guidelines and policies that should be followed in the process of development of Generic Geometry Library (GGL).

It is aimed to propose the GGL to the collection of  Boost C++ Libraries, so it is intentional to closely follow Boost conventions. As such, this document is based on  Boost Library Requirements and Guidelines and  Boost Header Policy.

Headers include order

  1. C Standard Library (using C++ library names, i.e. <cstdlib>)
  2. C++ Standard Library (std namespace)
  3. Boost C++ Libraries (boost namespace)
  4. Generic Geometry Library
  5. Other 3rd-party headers

Macros

All names of  preprocessor macros are always UPPERCASE and words/tokens are separated with underscore (_). Macro identifiers must not begin with one or more underscores, such names are reserved according to the  C++ Language Standard. Generally, it's a good practice to avoid macros if you can and use them only when you have to.

Include guards

Names of  include guards are constructed as follows:

GGL_<DIRECTORY 1>_<DIRECTORY N>_<FILE>_HPP

For example header ggl/strategies/distance_result.hpp defines GGL_STRATEGIES_DISTANCE_RESULT_HPP

It is not necessary to append _INCLUDED postfix. The GGL_ prefix should generate names long enough to consider them as unique.

Formatting

  • Prefered line length is 80 characters, however maximum is 100 characters in line.
  • Do not indent namespace blocks.
  • Prefer readable formatting and indentation of long template definition. Possible indentation layout is presented below:
    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
    };
    

Naming convention

  • Use m_ prefix for member variables as readable form. The Boost sample header gives no prefix/suffix at all. However, the m_ prefix is used in some (not many) boost libraries as well (e.g. math/tools/remez).
  • Do not prefix any names with underscore.

Miscellaneous

  • 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.
  • Order access specifiers for class members 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 are possible for typedef aliases required to be defined first.

Example

Guidelines summary example:

namespace a {

template <typename T>
struct sample1
{
    typedef T type;
};

template <typename T>
class sample2
{
public:
  void foo() {}
protected:
  void bar() {}
private:
  T m_member;
}; 

} // namespace a

Preparing unit tests

  • Testing algorithms is the main purpose.
  • Testing geometries is especially useful to test the concepts (segment) or specific methods (latlong), actually they might adapted or merged with the custom

tests (custom_linestring)

  • Core is a bit weird now, more core-tests might be added in future.

These are only basic guidelines and notes about tests structure:

  • test_main is provided by Boost
  • in test main: call test_all to test for all geometries, using different point types
  • in test_all call test_geometry for different geometries (linestring, polygon, box, etc.)

The above works for generic algorithms working the same for all geometries (such as append).

Other tests will need more specific testcases, so then:

  • in test_all call test_point, test_linestring, test_polygon, etc. (line in area.cpp, but the _area may be dropped, it is a bit redunant)
  • there are also specific cases for different strategies (like in area.cpp)