Code style and coding guidelines
================================

Based on

    * "C++ Programming Style Guidelines" by Geotechnical Software Services, Copyright © 1996 – 2011.
      The original document is available at `<http://geosoft.no/development/cppstyle.html>`_

    * NDN Platform "C++, C, C#, Java and JavaScript Code Guidelines".
      The original document available at `<http://named-data.net/codebase/platform/documentation/ndn-platform-development-guidelines/cpp-code-guidelines/>`_

1. Code layout and file naming
------------------------------

1.1. The code layout should generally follow the GNU coding standard layout for C,
extended it to C++.

    * Do not use tabs for indentation.
    * Indentation spacing is 2 spaces.
    * Lines should be within a reasonable range.  Lines longer than 100 columns should
      generally be avoided.

1.2. Whitespace

    * Conventional operators (``if``, ``for``, ``while``, and others) should be
      surrounded by a space character.
    * Commas should be followed by a white space.
    * Semicolons in for statments should be followed by a space character.

    Examples:

    .. code-block:: c++

        a = (b + c) * d; // NOT: a=(b+c)*d

        while (true) {     // NOT: while(true)
          ...

        doSomething(a, b, c, d);   // NOT: doSomething(a,b,c,d);

        for (i = 0; i < 10; i++) { // NOT: for(i=0;i<10;i++){
          ...

1.3. Namespaces should have the following form:

    .. code-block:: c++

        namespace example {

        code;
        moreCode;

        } // namespace example

    Note that code inside namespace is **not** indented. Avoid following:

    .. code-block:: c++

        // NOT
        //
        // namespace example {
        //
        //   code;
        //   moreCode;
        //
        // } // namespace example

1.4. The class declarations should have the following form:

    .. code-block:: c++

        class SomeClass : public BaseClass
        {
        public:
          ... <public methods> ...
        protected:
          ... <protected methods> ...
        private:
          ... <private methods> ...

        public:
          ... <public data> ...
        protected:
          ... <protected data> ...
        private:
          ... <private data> ...
        };

    ``public``, ``protected``, ``private`` may be repeated several times without
    interleaving (e.g., public, public, public, private, private) if this allows better
    readability of the code.

    Nested classes can be defined in appropriate visibility section, either in methods
    block, data block, or in a separate section (depending which one provides better code
    readability).

1.5. Method and function definitions should have the following form:

    .. code-block:: c++

        void
        someMethod()
        {
          ...
        }

        void
        SomeClass::someMethod()
        {
          ...
        }

1.6. The ``if-else`` class of statements should have the following form:

    .. code-block:: c++

        if (condition) {
          statements;
        }

        if (condition) {
          statements;
        }
        else {
          statements;
        }

        if (condition) {
          statements;
        }
        else if (condition) {
          statements;
        }
        else {
          statements;
        }

    or (less preferred):

    .. code-block:: c++

        if (condition)
          {
            statements;
          }
        else if (condition)
          {
            statements;
          }
        else
          {
            statements;
          }

1.7. A ``for`` statement should have the following form:

    .. code-block:: c++

        for (initialization; condition; update) {
          statements;
        }

    or (less preferred):

    .. code-block:: c++

        for (initialization; condition; update)
          {
            statements;
          }

    An empty for statement should have the following form:

    .. code-block:: c++

        for (initialization; condition; update)
          ;

    This emphasizes the fact that the for statement is empty and it makes it obvious for
    the reader that this is intentional.  Empty loops should be avoided however.

1.8. A ``while`` statement should have the following form:

    .. code-block:: c++

        while (condition) {
          statements;
        }

    or (less preferred):

    .. code-block:: c++

        while (condition)
          {
            statements;
          }

1.9. A ``do-while`` statement should have the following form:

    .. code-block:: c++

        do {
          statements;
        } while (condition);

1.10. A ``switch`` statement should have the following form:

    .. code-block:: c++

        switch (condition) {
        case ABC:
          statements;
          // Fallthrough

        case DEF:
          statements;
          break;

        case XYZ:
          statements;
          break;

        default:
          statements;
          break;
        }

    or (less preferred):

    .. code-block:: c++

        switch (condition)
          {
          case ABC:
            statements;
            // Fallthrough

          case DEF:
            statements;
            break;

          case XYZ:
            statements;
            break;

          default:
            statements;
            break;
          }

    The explicit ``Fallthrough`` comment should be included whenever there is a case
    statement without a break statement.  Leaving the break out is a common error, and it
    must be made clear that it is intentional when it is not there.

1.11. A ``try-catch`` statement should have the following form:

    .. code-block:: c++

        try {
          statements;
        }
        catch (Exception& exception) {
          statements;
        }

    or (less preferred):

    .. code-block:: c++

        try
          {
            statements;
          }
        catch (Exception& exception)
          {
            statements;
          }

1.12. The incompleteness of split lines must be made obvious.

    .. code-block:: c++

        totalSum = a + b + c +
                   d + e;
        function(param1, param2,
                 param3);
        for (int tableNo = 0; tableNo < nTables;
             tableNo += tableStep) {
          ...
        }

    Split lines occurs when a statement exceed the 80 column limit given above. It is
    difficult to give rigid rules for how lines should be split, but the examples above should
    give a general hint.In general:

    * Break after a comma.
    * Break after an operator.
    * Align the new line with the beginning of the expression on the previous line.

    Exceptions:

    * The following is the standard practice with operator<<:

        .. code-block:: c++

            std::cout << "Something here "
                      << "Something there" << std::endl;

1.13.  When class variables need to be initialized in the constructor, the initialization
should take the following form:

    .. code-block:: c++

        SomeClass::SomeClass(int value, const std::string& string)
          : m_value(value)
          , m_string(string)
          ...
        {
        }

    Each initialization should be put on a separate line, starting either with the colon
    for the first initialization or with comma for all subsequent initializations.

2. Naming Conventions
---------------------

2.1. C++ header files should have the extension ``.hpp``. Source files should have the
extension ``.cpp``

    File names should be all lower case. If the class name
    is a composite of several words, each word in a file name should be separated with a
    dash (-). A class should be declared in a header file and defined in a source file
    where the name of the files match the name of the class.

    ::

        my-class.hpp, my-class.cpp


2.2. Names representing types must be written in English in mixed case starting with upper case.

    .. code-block:: c++

        class MyClass;
        class Line;
        class SavingsAccount;

2.3. Variable names must be written in English in mixed case starting with lower case.

    .. code-block:: c++

        MyClass myClass;
        Line line;
        SavingsAccount savingsAccount;
        int theAnswerToLifeTheUniverseAndEverything;

2.4. Named constants (including enumeration values) must be all uppercase using underscore
to separate words.

    .. code-block:: c++

        const int MAX_ITERATIONS = 25;
        const std::string COLOR_RED = "red";
        static const double PI = 3.14;

    In some cases, it is a better (or is the only way for complex constants in header-only
    classes) to implement the value as a method:

    .. code-block:: c++

        int
        getMaxIterations()
        {
          return 25;
        }

2.5. Names representing methods or functions must be commands starting with a verb and
written in mixed case starting with lower case.

    .. code-block:: c++

        std::string
        getName()
        {
          ...
        }

        double
        computeTotalWidth()
        {
          ...
        }

2.6. Names representing namespaces should be all lowercase.

    .. code-block:: c++

        namespace model {
        namespace analyzer {

        ...

        } // namespace analyzer
        } // namespace model

2.7. Names representing generic template types should be a single uppercase letter

    .. code-block:: c++

        template<class T> ...
        template<class C, class D> ...

    However, when template parameter represents a certain concept and expected to have a
    certain interface, the name should be explicitly spelled out:

    .. code-block:: c++

        template<class FaceBase> ...
        template<class Packet> ...

2.8. Abbreviations and acronyms must not be uppercase when used as name.

    .. code-block:: c++

        exportHtmlSource(); // NOT: exportHTMLSource();
        openDvdPlayer();    // NOT: openDVDPlayer();

2.9. Global variables should have ``g_`` prefix

    .. code-block:: c++

        g_mainWindow.open();
        g_applicationContext.getName();

    In general, the use of global variables should be avoided.  Consider using singleton
    objects instead.

2.10. Private class variables should have ``m_`` prefix. Static class variables should have
``s_`` prefix.

    .. code-block:: c++

        class SomeClass
        {
        private:
          int m_length;

          static std::string s_name;
        };


2.11. Variables with a large scope should have long (explicit) names, variables with a small
scope can have short names.

    Scratch variables used for temporary storage or indices are best kept short.  A
    programmer reading such variables should be able to assume that its value is not used
    outside of a few lines of code. Common scratch variables for integers are ``i``,
    ``j``, ``k``, ``m``, ``n`` and for characters ``c`` and ``d``.

2.12. The name of the object is implicit, and should be avoided in a method name.

    .. code-block:: c++

        line.getLength(); // NOT: line.getLineLength();

    The latter seems natural in the class declaration, but proves superfluous in use, as
    shown in the example.

2.13. The terms ``get/set`` must be used where an attribute is accessed directly.

    .. code-block:: c++

        employee.getName();
        employee.setName(name);

        matrix.getElement(2, 4);
        matrix.setElement(2, 4, value);

2.14. The term ``compute`` can be used in methods where something is computed.

    .. code-block:: c++

        valueSet.computeAverage();
        matrix.computeInverse()

    Give the reader the immediate clue that this is a potentially time-consuming operation,
    and if used repeatedly, he might consider caching the result. Consistent use of the term
    enhances readability.

2.15. The term ``find`` can be used in methods where something is looked up.

    .. code-block:: c++

        vertex.findNearestVertex();
        matrix.findMinElement();

    Give the reader the immediate clue that this is a simple look up method with a minimum
    of computations involved. Consistent use of the term enhances readability.

2.16. Plural form should be used on names representing a collection of objects.

    .. code-block:: c++

        vector<Point> points;
        int values[];

    Enhances readability since the name gives the user an immediate clue of the type of
    the variable and the operations that can be performed on its elements.

2.17. The prefix ``n`` should be used for variables representing a number of objects.

    .. code-block:: c++

        nPoints, nLines

    The notation is taken from mathematics where it is an established convention for
    indicating a number of objects.


2.18. The suffix ``No`` should be used for variables representing an entity number.

    .. code-block:: c++

        tableNo, employeeNo

    The notation is taken from mathematics where it is an established convention for
    indicating an entity number.  An elegant alternative is to prefix such variables with
    an ``i``: ``iTable``, ``iEmployee``.  This effectively makes them named iterators.

2.19. The prefix ``is``, ``has``, ``need``, or similar should be used for boolean variables and
methods.

    .. code-block:: c++

        isSet, isVisible, isFinished, isFound, isOpen
        needToConvert, needToFinish

2.20. Complement names must be used for complement operations, reducing complexity by
symmetry.

    ::

        get/set, add/remove, create/destroy, start/stop, insert/delete,
        increment/decrement, old/new, begin/end, first/last, up/down, min/max,
        next/previous (and commonly used next/prev), open/close, show/hide,
        suspend/resume, etc.

    Pair ``insert/erase`` should be preferred.  ``insert/delete`` can also be used if it
    does not conflict with C++ delete keyword.

2.21. Variable names should not include reference to variable type (do not use Hungarian
notation).

    .. code-block:: c++

        Line* line; // NOT: Line* pLine;
                    // NOT: Line* linePtr;

        size_t nPoints; // NOT lnPoints

        char* name; // NOT szName

2.22. Negated boolean variable names should be avoided.

    .. code-block:: c++

        bool isError; // NOT: isNoError
        bool isFound; // NOT: isNotFound

2.23. Enumeration constants recommended to prefix with a common type name.

    .. code-block:: c++

        enum Color {
          COLOR_RED,
          COLOR_GREEN,
          COLOR_BLUE
        };

2.24. Exceptions can be suffixed with either ``Exception`` (e.g., ``SecurityException``) or
``Error`` (e.g., ``SecurityError``).

    The recommended method is to declare exception class ``Exception`` or ``Error`` as an
    inner class, from which the exception is thrown.  For example, when declaring class
    ``Foo`` that can throw errors, one can write the following:

    .. code-block:: c++

        #include <stdexcept>

        class Foo
        {
          class Error : public std::runtime_error
          {
          public:
            explicit
            Error(const std::string& what)
              : std::runtime_error(what)
            {
            }
          };
        };

    In addition to that, if class Foo is a base class or interface for some class
    hierarchy, then child classes should should define their own ``Error`` or
    ``Exception`` classes that are inherited from the parent's Error class.


2.25. Functions (methods returning something) should be named after what they return and
procedures (void methods) after what they do.

    Increase readability. Makes it clear what the unit should do and especially all the
    things it is not supposed to do. This again makes it easier to keep the code clean of
    side effects.

3. Miscellaneous
----------------

3.1. Exceptions can be used in the code, but should be used only in exceptional cases and
not in the primary processing path.

3.2. Header files must contain an include guard.

    For example, header file located in ``module/class-name.hpp`` or in
    ``src/module/class-name.hpp`` should have header guard in the following form:

    .. code-block:: c++

        #ifndef APP_MODULE_CLASS_NAME_HPP
        #define APP_MODULE_CLASS_NAME_HPP
        ...
        #endif // APP_MODULE_CLASS_NAME_HPP

    The name should follow the location of the file inside the source tree and prevents
    naming conflicts.  Header guard should be prefixed with the application/library name
    to avoid conflicts with other packaged and libraries.

3.3. Header files which are in the same source distribution should be included in
``"quotes"``, if possible with a path relative to the source file.  Header files for
system and other external libraries should be included in ``<angle brackets>``.

    .. code-block:: c++

        #include <string>
        #include <boost/lexical_cast.hpp>

        #include "util/random.hpp"

3.4. Include statements should be sorted and grouped. Sorted by their hierarchical position
in the system with low level files included first. Leave an empty line between groups
of include statements.

    .. code-block:: c++

        #include <fstream>
        #include <iomanip>

        #include <boost/lexical_cast.hpp>
        #include <boost/regex.hpp>

        #include "detail/pending-interest.hpp"
        #include "util/random.hpp"


3.5. Types that are local to one file only can be declared inside that file.


3.6. Implicit conversion is generally allowed.

    Implicit conversion between integer and floating point numbers can cause problems and
    should be avoided.

    Implicit conversion in single-argument constructor is usually undesirable. Therefore, all
    single-argument constructors should be marked 'explicit', unless implicit conversion is
    desirable. In that case, a comment should document the reason.

    Avoid C-style casts. Use ``static_cast``, ``dynamic_cast``, ``reinterpret_cast``,
    ``const_cast`` instead where appropriate.  Use ``static_pointer_cast``,
    ``dynamic_pointer_cast``, ``const_pointer_cast`` when dealing with ``shared_ptr``.


3.7. Variables should be initialized where they are declared.

    This ensures that variables are valid at any time. Sometimes it is impossible to
    initialize a variable to a valid value where it is declared:

    .. code-block:: c++

        int x, y, z;
        getCenter(&x, &y, &z);

    In these cases it should be left uninitialized rather than initialized to some phony
    value.

3.8. In most cases, class instance variables should not be declared public.

    The concepts of information hiding and encapsulation are violated by public variables. Use
    private variables and access methods instead.

    Exceptions to this rule:

    * when the class is essentially a dumb data structure with no or minimal behavior
      (equivalent to a C struct, also known as PODS). In this case it is appropriate to make
      the instance variables public by using struct.

    * when the class is used only inside the compilation unit, e.g., when implementing pImpl
      idiom (aka Bridge pattern) or similar cases.


3.9. C++ pointers and references should have their reference symbol next to the type rather
than to the name.

    .. code-block:: c++

        float* x; // NOT: float *x;
        int& y;   // NOT: int &y;

3.10. Implicit test for 0 should not be used other than for boolean variables and pointers.

    .. code-block:: c++

        if (nLines != 0)  // NOT: if (nLines)
        if (value != 0.0) // NOT: if (value)

3.11. When checking if ``shared_ptr`` points to an object, explicit ``static_cast<bool>``
must be used.

    ``shared_ptr`` in C++11 (unlike ``boost::shared_ptr``) does not have implicit
    conversion to bool.

3.12. Loop variables should be initialized immediately before the loop.

    .. code-block:: c++

        isDone = false;        // NOT: bool isDone = false;
        while (!isDone) {      //      // other stuff
          :                    //      while (!isDone) {
        }                      //        :
                               //      }

3.13. The form while (true) should be used for infinite loops.

    .. code-block:: c++

        while (true) {
          ...
        }

        // NOT:
        for (;;) { // NO!
          :
        }
        while (1) { // NO!
          :
        }

3.14. Complex conditional expressions must be avoided. Introduce temporary boolean variables
instead.

    .. code-block:: c++

        bool isFinished = (elementNo < 0) || (elementNo > maxElement);
        bool isRepeatedEntry = elementNo == lastElement;
        if (isFinished || isRepeatedEntry) {
          ...
        }

        // NOT:
        // if ((elementNo < 0) || (elementNo > maxElement) || elementNo == lastElement) {
        //  ...
        // }

    By assigning boolean variables to expressions, the program gets automatic
    documentation.  The construction will be easier to read, debug and maintain.

3.15. The conditional should be put on a separate line.

    .. code-block:: c++

        if (isDone)         // NOT: if (isDone) doCleanup();
          doCleanup();

    This is for debugging purposes. When writing on a single line, it is not apparent
    whether the test is really true or not.

3.16. Assignment statements in conditionals must be avoided.

    .. code-block:: c++

        File* fileHandle = open(fileName, "w");
        if (!fileHandle) {
          ...
        }

        // NOT
        // if (!(fileHandle = open(fileName, "w"))) {
        //  ..
        // }

3.17. The use of magic numbers in the code should be avoided. Numbers other than 0 and 1
should be considered declared as named constants instead.

    If the number does not have an obvious meaning by itself, the readability is enhanced
    by introducing a named constant instead.  A different approach is to introduce a method
    from which the constant can be accessed.

3.18. Floating point constants should always be written with decimal point, at least one
    decimal, and without omitting 0 before decimal point.

    .. code-block:: c++

        double total = 0.0;     // NOT: double total = 0;
        double someValue = 0.1; // NOT double someValue = .1;
        double speed = 3.0e8;   // NOT: double speed = 3e8;
        double sum;
        ...
        sum = (a + b) * 10.0;

3.19. ``goto`` should not be used.

Goto statements violate the idea of structured code.  Only in some very few cases (for
instance breaking out of deeply nested structures) should goto be considered, and only if
the alternative structured counterpart is proven to be less readable.

3.20. "0" should be used instead of "NULL".

3.21. Logical units within a block should be separated by one blank line.

    .. code-block:: c++

        Matrix4x4 matrix = new Matrix4x4();

        double cosAngle = Math.cos(angle);
        double sinAngle = Math.sin(angle);

        matrix.setElement(1, 1, cosAngle);
        matrix.setElement(1, 2, sinAngle);
        matrix.setElement(2, 1, -sinAngle);
        matrix.setElement(2, 2, cosAngle);

        multiply(matrix);

    Enhance readability by introducing white space between logical units of a block.

3.22. Variables in declarations can be left aligned.

    .. code-block:: c++

        AsciiFile* file;
        int        nPoints;
        float      x, y;

    Enhance readability. The variables are easier to spot from the types by alignment.

3.23. Use alignment wherever it enhances readability.

    .. code-block:: c++

        value = (potential        * oilDensity)   / constant1 +
                (depth            * waterDensity) / constant2 +
                (zCoordinateValue * gasDensity)   / constant3;

        minPosition =     computeDistance(min,     x, y, z);
        averagePosition = computeDistance(average, x, y, z);

    There are a number of places in the code where white space can be included to enhance
    readability even if this violates common guidelines. Many of these cases have to do
    with code alignment. General guidelines on code alignment are difficult to give, but
    the examples above should give a general clue.

3.24. All comments should be written in English.

    In an international environment English is the preferred language.

3.25. Use ``//` for all comments, including multi-line comments.

    .. code-block:: c++

        // Comment spanning
        // more than one line.

    Since multilevel C-commenting is not supported, using ``//`` comments ensure that it
    is always possible to comment out entire sections of a file using ``/* */`` for
    debugging purposes etc.

    There should be a space between the ``//`` and the actual comment, and comments should
    always start with an upper case letter and end with a period.

    However, method and class documentation comments should use ``/** */`` style for
    Doxygen, JavaDoc and JSDoc.

3.26. Comments should be included relative to their position in the code.

    .. code-block:: c++

        while (true) {
          // Do something
          something();
        }

        // NOT:
        while (true) {
        // Do something
          something();
        }

    This is to avoid that the comments break the logical structure of the program.
