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 (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.

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}; // not supported by GCC 4.6
          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. 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. ``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 bundled with additional diagnostic information, including
filename, line number, and function name from where the exception was thrown.
