ndn-cxx 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
--------------

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:        // 2 space indent
            statements;    // 4 space indent
            // Fallthrough

          case DEF:
            statements;
            break;

          case XYZ: {
            statements;
            break;
          }

          default:
            statements;
            break;
        }

    When curly braces are used inside a ``case`` block, the braces must cover the entire
    ``case`` block.

    .. code-block:: c++

        switch (condition) {
          // Correct style
          case A0: {
            statements;
            break;
          }

          // Correct style
          case A1: {
            statements;
            // Fallthrough
          }

          // Incorrect style: braces should cover the entire case block
          case B: {
            statements;
          }
          statements;
          break;

          default:
            break;
        }

    The following style is still allowed when none of the ``case`` blocks has curly braces.

    .. code-block:: c++

        switch (condition) {
        case ABC:        // no indent
          statements;    // 2 space indent
          // Fallthrough

        case DEF:
          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 (const Exception& exception) {
          statements;
        }

    or (less preferred):

    .. code-block:: c++

        try
          {
            statements;
          }
        catch (const 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.

1.14. A range-based ``for`` statement should have the following form:

    .. code-block:: c++

        for (T i : range) {
          statements;
        }

1.15. A lambda expression should have the following form:

    .. code-block:: c++

        [&capture1, capture2] (T1 arg1, T2 arg2) {
          statements;
        }

        [&capture1, capture2] (T1 arg1, T2 arg2) mutable {
          statements;
        }

        [this] (T arg) {
          statements;
        }

    If the function has no parameters, ``()`` should be omitted.

    .. code-block:: c++

        [&capture1, capture2] {
          statements;
        }

    Capture-all (``[&]`` and ``[=]``) is permitted, but its usage should be minimized.
    Only use capture-all when it significantly simplifies code and improves readability.

    .. code-block:: c++

        [&] (T arg) {
          statements;
        }

        [=] (T arg) {
          statements;
        }

    Trailing return type should be omitted. Write them only when compiler cannot deduce
    return type automatically, or when it improves readability.
    ``()`` is required by C++ standard when trailing return type is written.

    .. code-block:: c++

        [] (T arg) -> int {
          statements;
        }

        [] () -> int {
          statements;
        }

    If the function body has only one line, and the whole lambda expression can fit in one line,
    the following form is also acceptable:

    .. code-block:: c++

        [&capture1, capture2] (T1 arg1, T2 arg2) { statement; }

    No-op can be written in a more compact form:

    .. code-block:: c++

        []{}

1.16. List initialization should have the following form:

    .. code-block:: c++

        T object{arg1, arg2};

        T{arg1, arg2};

        new T{arg1, arg2};

        return {arg1, arg2};

        function({arg1, arg2}, otherArgument);

        object[{arg1, arg2}];

        T({arg1, arg2})

        class Class
        {
        private:
          T m_member = {arg1, arg2};
          static T s_member = {arg1, arg2};
        };

        Class::Class()
          : m_member{arg1, arg2}
        {
        }

        T object = {arg1, arg2};

    An empty braced-init-list is written as ``{}``. For example:

    .. code-block:: c++

        T object{};

        T object = {};

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. *(removed)*

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. ``nullptr`` should be used to represent a null pointer, instead of "0" or "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.

3.27. Use ``BOOST_ASSERT`` and ``BOOST_ASSERT_MSG`` for runtime assertions.

    .. code-block:: c++

        int x = 1;
        int y = 2;
        int z = x + y;
        BOOST_ASSERT(z - y == x);

    The expression passed to ``BOOST_ASSERT`` MUST NOT have side effects,
    because it MAY NOT be evaluated in release builds.

3.28. Use ``static_assert`` for static assertions.

    .. code-block:: c++

        class BaseClass
        {
        };

        class DerivedClass : public BaseClass
        {
        };

        static_assert(std::is_base_of<BaseClass, DerivedClass>::value,
                      "DerivedClass must inherit from BaseClass");

3.29. ``auto`` type specifier MAY be used for local variables, if a human reader
      can easily deduce the actual type.

    .. code-block:: c++

        std::vector<int> intVector;
        auto i = intVector.find(4);

        auto stringSet = std::make_shared<std::set<std::string>>();

    ``auto`` SHOULD NOT be used if a human reader cannot easily deduce the actual type.

    .. code-block:: c++

        auto x = foo(); // BAD if the declaration of foo() isn't nearby

    ``const auto&`` SHOULD be used to represent constant reference types.
    ``auto&&`` SHOULD be used to represent mutable reference types.

    .. code-block:: c++

        std::list<std::string> strings;

        for (const auto& str : strings) {
          statements; // cannot modify `str`
        }
        for (auto&& str : strings) {
          statements; // can modify `str`
        }

3.30. Annotate with ``override`` or ``final`` when overriding a virtual method or destructor.

    ``virtual`` should still be used along with ``override`` and ``final``,
    so that a human reader can easily recognize a virtual method
    without looking toward the end of the function signature.

    .. code-block:: c++

        class Stream
        {
        public:
          virtual void
          open();
        };

        class InputStream : public Stream
        {
        public:
          virtual void
          open() override;
        };

        class Console : public InputStream
        {
        public:
          virtual void
          open() override;
        };

    ndn-cxx declares ``NDN_CXX_DECL_OVERRIDE`` and ``NDN_CXX_DECL_FINAL`` macros that
    expand to ``override`` and ``final`` if the compiler supports this feature,
    but expand to nothing with older compilers.
    These must be used in place of ``override`` and ``final``,
    so that ndn-cxx remains compatible with older compilers.

    ``NDN_CXX_DECL_OVERRIDE`` and ``NDN_CXX_DECL_FINAL`` macros are for ndn-cxx internal use.
    Other projects, if adopting this style guide, should define their own macros if needed.

3.31. The recommended way to throw an exception derived from ``std::exception`` is to use
the ``BOOST_THROW_EXCEPTION``
`macro <http://www.boost.org/doc/libs/1_42_0/libs/exception/doc/BOOST_THROW_EXCEPTION.html>`__.
Exceptions thrown using this macro will be augmented with additional diagnostic information,
including file name, line number, and function name from where the exception was thrown.
