C++ Meta-Programming Doxygen Documentation

C++ meta-programming doxygen documentation

Use preprocessor macros. Here's an example from the not-yet-official Boost.XInt library (presently queued for review for inclusion in Boost):

#ifdef BOOST_XINT_DOXYGEN_IGNORE
// The documentation should see a simplified version of the template
// parameters.
#define BOOST_XINT_INITIAL_APARAMS ...
#define BOOST_XINT_CLASS_APARAMS ...
#define BOOST_XINT_CLASS_BPARAMS other
#define BOOST_XINT_APARAMS ...
#define BOOST_XINT_BPARAMS other
#else
#define BOOST_XINT_INITIAL_APARAMS \
class A0 = parameter::void_, \
class A1 = parameter::void_, \
class A2 = parameter::void_, \
class A3 = parameter::void_, \
class A4 = parameter::void_, \
class A5 = parameter::void_
#define BOOST_XINT_CLASS_APARAMS class A0, class A1, class A2, class A3, \
class A4, class A5
#define BOOST_XINT_APARAMS A0, A1, A2, A3, A4, A5
#define BOOST_XINT_CLASS_BPARAMS class B0, class B1, class B2, class B3, \
class B4, class B5
#define BOOST_XINT_BPARAMS B0, B1, B2, B3, B4, B5
#endif

Use the #defined macro names instead of the template parameters, everywhere you need them, like so:

/*! \brief The integer_t class template.

This class implements the standard aribitrary-length %integer type.

[...lots more documentation omitted...]
*/
template<BOOST_XINT_INITIAL_APARAMS>
class integer_t: virtual public detail::integer_t_data<BOOST_XINT_APARAMS>,
public detail::nan_functions<detail::integer_t_data<BOOST_XINT_APARAMS>::
NothrowType::value, // ...lots more base classes omitted...
{
// ...etcetera

And put lines like these in the Doxyfile:

PREDEFINED             = BOOST_XINT_DOXYGEN_IGNORE

EXPAND_AS_DEFINED = BOOST_XINT_INITIAL_APARAMS \
BOOST_XINT_CLASS_APARAMS \
BOOST_XINT_CLASS_BPARAMS \
BOOST_XINT_APARAMS \
BOOST_XINT_BPARAMS

The result is that Doxygen sees either "..." or "other" for the template parameters, and the compiler sees the real ones. If you describe the template parameters in the documentation for the class itself, then the user of the library will only need to see them in the one place that he's likely to look for them; they'll be hidden everywhere else.

As an additional advantage to this design, if you ever need to make changes to the template parameter lists, you only need to change them in the macro definitions and the functions that actually use the changed parameters. Everything else will adapt automatically.

How to document C++ templates and template metafunctions with doxygen?

I don't think it is possible use document advanced template constructs with doxygen since it was originally designed for the object oriented paradigm and not metaprograming. As an illustration,GNU STL (libstdc++) uses doxygen but does a poor job of documenting metaprograming in the STL.

On the other hand, boost uses its own tools: QuickBook uses standalone text files and doxygen documented source to generate BoostBook markup (extension of DocBook) which in turns generates html/pdf. The result is more informative than for libstdc++ but obviously involves a little more work from the dev.

Since boost documentation is arguably one of the best for metaprograming you could go that route, especially since it complements doxygen - you can reuse your existing markup.

Although it does not exactly answer your question, you might be interested in recent clang developments. When building clang with --with-extra-options=-Wdocumentation it semantically checks your doxygen markup with your code and generates documentation warnings. Forces you to keep docs/code synchronized.

How to use doxygen in a project containing both C++ and Python (multi-programming language project)

First off, thank you albert and shawnhcorey for your quick responses.
I tried what you suggested, and made the following modifications to parse documentation comments from files written in both languages:

In Doxyfile

INPUT = include/my_package/ scripts/my_package/

Both directories are separated by space.

Then,

FILE_PATTERNS = *.h *.py

The two wildcards patterns are also separated by a space.

Back to where you placed your doxyfile, then run

doxygen

And off you go!

Linked Qt documentation to own Doxygen documentation

Find a workaround finally following the workarounds proposed by another user on this topic.

Doxygen: how to document a non-C function using only its documentation block but not the code?

There are various options

  1. You could write an input filter that translates your code into something that looks enough like C for doxygen to parse it (see also FILTER_PATTERNS and EXTENSION_MAPPING).

  2. You could create a dummy C file with the function prototypes and document those instead. You could put the documentation in the C file or in your programming language if you use the approach you mentioned in the question.

  3. If your language supports a C preprocessor, you could use doxygen's C preprocessor to hide parts of the file from doxygen, i.e.

    #if DOXYGEN_ONLY
    /**
    \brief some brief description here
    \param[in](param) mandatory parameter description
    \param[in](option) optional parameter description
    */
    void foo(param,option);
    #endif
    foo(param, {option}) { ... };

    and then define the following in the config file:

    PREDEFINED = DOXYGEN_ONLY

Documenting a C++ concept using doxygen?

What you can do is define a custom tag called Concept, which you can then use as you describe. An example of this is to use the alias mechanism in Doxygen, something like:

ALIASES += "con=\xrefitem con \"Concept\" \"Concepts\" "

How to validate whether a c++ program is well documented using Doxygen format or not?

Doxygen already provides some useful configuration options:

WARN_IF_UNDOCUMENTED

If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag will automatically be disabled.

WARN_IF_DOC_ERROR

If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for potential errors in the documentation, such as not documenting some parameters in a documented function, or documenting parameters that don't exist or using markup commands wrongly.

WARN_NO_PARAMDOC

This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that are documented, but have no documentation for their parameters or return value. If set to NO, doxygen will only warn about wrong or incomplete parameter documentation, but not about the absence of documentation. If EXTRACT_ALL is set to YES then this flag will automatically be disabled.

And finally:

WARN_AS_ERROR

If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but at the end of the doxygen process doxygen will return with a non-zero status.

Possible values are: NO, YES and FAIL_ON_WARNINGS.

So let's put all this together. The Doxyfile needs to contain the following settings:

# EXTRACT_ALL = NO is needed, or otherwise some of the 
# other flags are disabled automatically.
EXTRACT_ALL = NO
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = YES
# WARN_AS_ERROR could also be NO, but then
# it stops after the first documentation error.
WARN_AS_ERROR = YES

That way doxygen will show all undocumented code and it will exit with a non-zero, if there is undocumented code.

Documenting macros using Doxygen

The primary problem seems to attend putting the documentation comment into the macro. I find that if I put the doc comment with the macro invocation then it is reflected in the generated documentation; otherwise, it is not. Naturally, you have to configure Doxygen to expand macros, which is not its default behavior.

For example:

/** @brief This is my initial struct. */
typedef struct
{
ae_f32 v; /**< Value. */
ae_int32 s; /**< Scale. */
} ae_f32_t;

#define DECLARE_TYPE(N) \
typedef ae_f32_t ae_q##N##_t

DECLARE_TYPE(31); /**< @brief This is my Q31 struct */
DECLARE_TYPE(25); /**< @brief This is my Q25 struct */

(I have also moved the terminating semicolon out of the macro, but with the doc comment also being moved, this is a matter of style only.)

This makes some sense, since one of the things the preprocessor does is convert comments to whitespace. It's not obvious that Doxygen must do that in a way that causes it to ignore doc comments in macros, but it is not unreasonable for it to do so.



Related Topics



Leave a reply



Submit