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 the namespace is **not** indented. Avoid the following:

    .. code-block:: c++

        // WRONG
        //
        // 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
            [[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 ``[[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::analyzer {

        ...

        } // namespace model::analyzer

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