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 is available at `<https://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 the following:

    .. code-block:: c++

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

1.4. 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 improves
    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;
        }

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

    .. 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 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;
        }

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
            NDN_CXX_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;
            NDN_CXX_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
          NDN_CXX_FALLTHROUGH;

        case DEF:
          statements;
          break;

        default:
          statements;
          break;
        }

    The ``NDN_CXX_FALLTHROUGH`` annotation must be included whenever there is
    a case 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.
    Moreover, modern compilers will warn when a case that falls through is not
    explicitly annotated.

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

    .. 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 occur when a statement exceeds the column limit given in rule 1.1. 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 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;
        }

        [&] (T arg) {
          statements;
        }

        [=] (T arg) {
          statements;
        }

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

    .. code-block:: c++

        [&capture1, capture2] {
          statements;
        }

    Trailing return types should be omitted whenever possible. Add it only when the compiler
    cannot deduce the return type automatically, or when it improves readability. Note that
    ``()`` is required by the C++ standard when ``mutable`` or a trailing return type is used.

    .. 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; }

    A no-op lambda 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})

        T object = {arg1, arg2};

        class Class
        {
        private:
          T m_member{arg1, arg2};
          static T s_member = {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++

        static int          // declare constexpr if possible
        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 a template parameter represents a certain concept and is expected
    to have a certain interface, the name should be explicitly spelled out.

    .. code-block:: c++

        template<class InputIterator> ...
        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. All non-static data members of a class should be prefixed with ``m_`` unless they
are public. Similarly, non-public static data members should be prefixed with ``s_``.

    .. 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 ``Num`` or ``No`` should be used for variables representing an entity number.

    .. code-block:: c++

        tableNum, tableNo, employeeNum, employeeNo

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/erase,
        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.

    The pair ``insert/erase`` is preferred. ``insert/delete`` can also be used if it
    does not conflict with the ``delete`` keyword of C++.

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 an exception class ``Exception`` or ``Error`` as
    a nested type inside the class from which the exception is thrown.  For example, when
    defining a class ``Foo`` that can throw errors, one can write the following:

    .. code-block:: c++

        #include <stdexcept>

        class Foo
        {
        public:
          class Error : public std::runtime_error
          {
          public:
            // You can inherit constructors from std::runtime_error like this:
            using std::runtime_error::runtime_error;

            // Additional constructors, if desired, can be declared as usual:
            Error(const std::string& what, const std::exception& inner)
              : std::runtime_error(what + ": " + inner.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, a header file named ``module/class-name.hpp`` or
    ``src/module/class-name.hpp`` should have a 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 macro name should reflect the path of the header file relative to the root of the
    source tree, in order to prevent naming conflicts. The header guard should be prefixed
    with the application/library name to avoid conflicts with other packages and libraries.

3.3. Include directives for system headers and other external libraries should use
``<angle brackets>``. Header files in the same source code repository should be included
using ``"quotes"``.

    .. code-block:: c++

        #include "ndn-cxx/util/random.hpp"

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

    All of a project's header files should be included with their path relative to
    the project's source directory. The use of UNIX directory shortcuts ``.``
    (the current directory) and ``..`` (the parent directory) is discouraged.

3.4. Include statements should be grouped. Same-project headers should be included first.
Leave an empty line between groups of include statements. Sort alphabetically within a group.
For example, the include section of ``ndn-cxx/foo/bar.cpp`` may look like this:

    .. code-block:: c++

        #include "ndn-cxx/impl/pending-interest.hpp"
        #include "ndn-cxx/util/random.hpp"

        #include <cstdlib>
        #include <fstream>
        #include <iomanip>

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

3.5. Definitions that are local to only one ``.cpp`` file should be declared inside that
file and be placed in an unnamed namespace or declared ``static``.

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 constructors that can be called with a single argument 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 for this.
    As an exception, copy and move constructors should not be explicit, since they do not
    perform type conversion.
    Constructors that cannot be called with a single argument may omit ``explicit``.
    Constructors that take a single ``std::initializer_list`` parameter should also omit
    ``explicit``, in order to support copy-initialization.

    Avoid C-style casts.
    Use ``static_cast``, ``dynamic_cast``, ``const_cast``, ``reinterpret_cast``, or
    ``bit_cast`` instead where appropriate.
    Use ``static_pointer_cast``, ``dynamic_pointer_cast``, or ``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 data members should not be declared ``public``.

    Public data members violate the concepts of information hiding and encapsulation.
    Use private variables and public accessor methods instead.

    Exceptions to this rule:

    * When the class is essentially a passive data structure with no or minimal behavior
      (equivalent to a C struct, also known as POD type). In this case, all fields should
      be public and the keyword ``struct`` should be used instead of ``class``.

    * 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)

        int* ptr = ...
        if (ptr)            // OK
        if (ptr != nullptr) // also OK

3.11. *(removed)*

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

    .. code-block:: c++

        bool 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 literals should always be written with a decimal point, at least one
decimal, and without omitting 0 before the 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 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. License boilerplate should use ``/* */`` style.

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 compile-time 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. The ``auto`` type specifier may be used for local variables if a human reader can
easily deduce the actual type, or if it makes the code safer.

    .. code-block:: c++

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

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

        std::vector<std::string> strings;
        for (const auto& str : strings) { // OK, iterating over the elements of a container
          std::cout << str;
        }

        obj.onEvent([] (auto&&...) { std::cout << "hi!"; }); // OK, unused lambda parameters

        auto x = foo(); // BAD unless foo() is declared nearby or has a well-known prototype

3.30. Use the ``override`` or ``final`` specifier when overriding a virtual
member function or a virtual destructor.

    ``virtual`` must not be used along with ``final`` so that the compiler can generate
    an error when a final function does not override.

    ``virtual`` should not be used along with ``override`` for consistency with ``final``.

    .. code-block:: c++

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

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

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

3.31. The recommended way to throw an exception derived from ``std::exception`` is to use
``NDN_THROW`` or one of the other ``NDN_THROW_*`` macros.

    Exceptions thrown using these macros will be augmented with additional diagnostic
    information, including the file name, line number, and function name from which
    the exception was thrown.

    The extended diagnostic information contained in the exception can be printed with
    ``boost::diagnostic_information()``.

    .. code-block:: c++

        #include <boost/exception/diagnostic_information.hpp>
        #include <iostream>

        try {
          operationThatMayThrow();
        }
        catch (const std::exception& e) {
          std::cerr << boost::diagnostic_information(e);
        }
