skills/doxygen-style.md
This skill describes the exact Doxygen documentation conventions used across
taskflow/**/*.hpp. Follow it precisely — formatting deviations (stray ///
comments, wrong tag order, missing examples) are the most common review
feedback on doc passes in this repo.
/** ... */ block comments for Doxygen documentation./// line comments (including trailing ///< field
comments) and never use multi-star banner comments (/********/).* . Lines start flush
left (or at the member's indentation level), with no leading asterisk.`x`) for inline code/identifiers instead
of @c x — Doxygen's @c command doesn't always render reliably in this
codebase's setup. Reserve @c only for cases already in surrounding code
that you're not otherwise touching.Wrong:
/**
* @brief does something
*/
///< trailing field comment
/********************************/
Right:
/**
@brief does something
*/
Every documented function, method, or class follows this fixed order:
@brief — one line, imperative/descriptive, no trailing period required.@class (classes only) — immediately before or after @brief.@tparam (one per template
parameter, in declaration order), then @param (one per parameter, in
declaration order), then @return.@code{.cpp} ... @endcode — a minimal, realistic usage example.@note, @warning — caveats, thread-safety notes, lifetime rules. These
always come last, after the @code example. Prefer @note by default;
reserve @warning for cases describing actual undefined behavior or
correctness/safety hazards. Avoid @attention — use @note instead.Skip any tag that doesn't apply (e.g., a void-returning function has no
@return; a non-template function has no @tparam). Never reorder the tags
that are present.
Template skeleton:
/**
@brief <one-line summary>
@tparam T <template parameter description>
@param x <parameter description>
@return <return value description>
<Explanation paragraph(s): what it does, how, and why, in plain prose.>
@code{.cpp}
<minimal realistic usage example>
@endcode
@note <caveat, e.g. thread-safety, lifetime conditions; use @warning instead for actual UB/safety hazards>
*/
Free function:
/**
@brief rounds the given 64-bit unsigned integer to the nearest power of 2
@tparam T 64-bit unsigned integral type
@param x the number to round up
@return the smallest power of 2 that is greater than or equal to @c x
This overload participates in overload resolution only when @c T is an
8-byte unsigned integral type. It repeatedly fills in the lower bits of
<tt>x - 1</tt> until all bits below the highest set bit are 1, then adds 1
to obtain the next power of 2.
@code{.cpp}
tf::next_pow2(uint64_t{17}); // returns 32
tf::next_pow2(uint64_t{32}); // returns 32
@endcode
*/
template <typename T>
requires (std::is_unsigned_v<std::decay_t<T>> && sizeof(T) == 8)
constexpr T next_pow2(T x) { ... }
Class member with multiple caveats:
/**
@brief checks if the given number is a power of 2
@tparam T integral type of the input
@param x The integer to check.
@return `true` if `x` is a power of 2, otherwise `false`.
This function determines if the given integer is a power of 2 by testing
that exactly one bit is set, i.e., <tt>x & (x - 1) == 0</tt>, while also
excluding zero.
@code{.cpp}
tf::is_pow2(8); // true
tf::is_pow2(10); // false
@endcode
@note This function is constexpr and can be evaluated at compile time.
*/
Class-level doc (uses @class, no signature tags, @note last since
there's no separate member doc to attach it to):
/**
@class Xorshift
@brief class to create a fast xorshift-based pseudo-random number generator
@tparam T unsigned integral type used as the internal state (supported uint32_t and uint64_t)
This class implements a lightweight xorshift pseudo-random number generator
suitable for performance-critical paths such as schedulers, work-stealing
victim selection, and randomized backoff.
@note
The internal state must be seeded with a non-zero value.
This class is not thread-safe. Each thread should maintain its own instance.
*/
doxygen/Doxyfile's INPUT are rendered into the
public docs. Check that list before assuming a header is user-facing.EXTRACT_ALL = NO and EXTRACT_PRIVATE = NO in doxygen/Doxyfile mean
@private-tagged entities and private class members are never rendered.
Apply the syntax cleanup (no ///, no banner stars) to these for
consistency, but don't bother adding @code examples — they aren't
user-facing.// comments on genuinely internal/private members (e.g. a private
nested helper struct never reachable from the public API) should be left
as-is; they aren't Doxygen comments and don't need conversion.grep -n "^\s*///" <file> — must return nothing.grep -n "/\*\*\*\|\*\*\*\*" <file> — must return nothing (no banner-star
comments).g++ -std=c++20 -I. -fsyntax-only <file> — must compile clean (ignore the
benign #pragma once in main file warning).@code examples, to confirm they're not just plausible
but actually correct.