Extraction
The filters are the gate at the front of the pipeline. They decide which symbols enter the corpus. The options on this page are the next stage: they decide how MrDocs interprets and arranges the symbols that survived the filters. Which inherited members appear on a class page, the order members are listed in, how related declarations are grouped (overload sets, SFINAE expressions, function objects), what MrDocs infers from doc comments (briefs, relations, function metadata), and the escape hatches for headers the compiler cannot find. The Extraction reference lists every option.
Ordering members
By default, members appear alphabetically within each kind. The sort-members family overrides that order when you want a more conventional grouping (constructors first, destructors first, conversions and relational operators last, and so on).
/// A class declared with members in deliberately
/// scattered order to show how sorting affects the
/// rendered member list.
struct gadget
{
/// Refresh the gadget.
void refresh();
/// Construct a gadget.
gadget();
/// Hide the gadget.
void hide();
/// Show the gadget.
void show();
/// Destroy the gadget.
~gadget();
};
mrdocs.ymlsort-members: true
gadget
A class declared with members in deliberately scattered order to show how sorting affects the rendered member list.
Synopsis
Declared in <sort‐members.cpp>
struct gadget;
Member Functions
Name |
Description |
|
Construct a gadget. |
|
Destroy the gadget. |
Hide the gadget. |
|
Refresh the gadget. |
|
Show the gadget. |
gadget::gadget
Construct a gadget.
Synopsis
Declared in <sort‐members.cpp>
gadget();
gadget::~gadget
Destroy the gadget.
Synopsis
Declared in <sort‐members.cpp>
~gadget();
gadget::hide
Hide the gadget.
Synopsis
Declared in <sort‐members.cpp>
void
hide();
gadget::refresh
Refresh the gadget.
Synopsis
Declared in <sort‐members.cpp>
void
refresh();
gadget::show
Show the gadget.
Synopsis
Declared in <sort‐members.cpp>
void
show();
The other sort switches (sort-members-ctors-1st, sort-members-dtors-1st, sort-members-assignment-1st, sort-members-conversion-last, sort-members-relational-last) refine which member kinds float to the top or sink to the bottom. sort-members-by and sort-namespace-members-by pick between alphabetical and declaration order.
Overload sets
A C++ overload set is many functions sharing a name. overloads merges them into a single page so the reader sees the whole set at once instead of one page per signature:
/** Compute the absolute value of an integer.
One overload takes `int` and the other `long`,
so the documentation page lists both side by side.
*/
int abs(int x);
/// @copydoc abs(int)
long abs(long x);
mrdocs.ymloverloads: true
abs
Compute the absolute value of an integer.
Synopses
Declared in <overloads.cpp>
Compute the absolute value of an integer.
int
abs(int x);
Compute the absolute value of an integer.
long
abs(long x);
abs
Compute the absolute value of an integer.
Synopsis
Declared in <overloads.cpp>
int
abs(int x);
Description
One overload takes int and the other long, so the documentation page lists both side by side.
abs
Compute the absolute value of an integer.
Synopsis
Declared in <overloads.cpp>
long
abs(long x);
Description
One overload takes int and the other long, so the documentation page lists both side by side.
SFINAE constraints
sfinae rewrites SFINAE constraints into a readable form instead of the raw enable_if machinery:
#include <type_traits>
/** Multiply by two, but only for integers.
The `std::enable_if_t` SFINAE on the return type
restricts the overload to integral arguments.
*/
template <class T>
std::enable_if_t<std::is_integral_v<T>, T>
twice(T x);
mrdocs.ymlsfinae: true
twice
Multiply by two, but only for integers.
Synopsis
Declared in <sfinae.cpp>
template<class T>
T
twice(T x)
requires std::is_integral_v<T>;
Description
The std::enable_if_t SFINAE on the return type restricts the overload to integral arguments.
Algorithm function objects
auto-function-objects detects the Algorithm Function Object (AFO) idiom and presents the variable’s page as if it were a function, using the call operator’s doc comment, parameters, and return type:
include/numerics/clamp.hppnamespace numerics {
struct clamp_fn
{
/** Constrain a value to the inclusive range `[lo, hi]`.
Returns `lo` when `v < lo`, `hi` when `hi < v`, otherwise `v`.
Behavior is undefined if `hi < lo`.
@tparam T A type comparable with `operator<`.
@param v The value to constrain.
@param lo The inclusive lower bound.
@param hi The inclusive upper bound.
@return A copy of `v`, `lo`, or `hi`, whichever lies within the range.
*/
template <class T>
T operator()(T const& v, T const& lo, T const& hi) const;
};
inline constexpr clamp_fn clamp = {};
}
mrdocs.ymlauto-function-objects: true
numerics::clamp
Constrain a value to the inclusive range [lo, hi].
Synopsis
Declared in <numerics/clamp.hpp>
template<class T>
T
clamp(
T const& v,
T const& lo,
T const& hi);
|
This function is defined as an Algorithm Function Object (AFO). |
Description
Returns lo when v < lo, hi when hi < v, otherwise v. Behavior is undefined if hi < lo.
Return Value
A copy of v, lo, or hi, whichever lies within the range.
Template Parameters
Name |
Description |
T |
A type comparable with |
Parameters
Name |
Description |
v |
The value to constrain. |
lo |
The inclusive lower bound. |
hi |
The inclusive upper bound. |
When auto-detection misses an AFO (the call-operator type has extra members, or the variable is not the only AFO-shaped constant in its scope), tag the variable with the @functionobject doc-comment command. Same effect, declared next to the symbol rather than left to inference.
|
Inferred metadata
MrDocs fills several kinds of metadata from the signature when the doc comment leaves them out. Each kind is governed by its own switch.
Briefs
By default, the first sentence of a doc comment becomes the brief and the rest becomes the detailed description. auto-brief is on by default; turn it off if you want every brief written explicitly with @brief.
/** Truncate a string to the given length.
The first sentence of this comment becomes the
brief; the rest is the description.
*/
void truncate(char* s, int n);
mrdocs.ymlauto-brief: true
truncate
Truncate a string to the given length.
Synopsis
Declared in <auto‐brief.cpp>
void
truncate(
char* s,
int n);
Description
The first sentence of this comment becomes the brief; the rest is the description.
Non-member functions
The "non-member functions" section on a class page is very useful to gather free functions that operate on the class, but it is a pain to maintain by hand. auto-relates is on by default to do the work for you. It looks for free functions that take the class as a parameter or return it and lists them under the class’s "Non-Member Functions" section, without needing any explicit tagging in the doc comment.
/** A two-dimensional point.
*/
struct point
{
double x;
double y;
};
/** Print a point to stdout.
The free function takes `point` as its only
parameter, so it gets attached to `point` as a
related function.
*/
void print(point p);
mrdocs.ymlauto-relates: true
point
A two‐dimensional point.
Synopsis
Declared in <auto‐relates.cpp>
struct point;
Data Members
Name |
Non-Member Functions
Name |
Description |
Print a point to stdout. |
point::x
Synopsis
Declared in <auto‐relates.cpp>
double x;
point::y
Synopsis
Declared in <auto‐relates.cpp>
double y;
Print a point to stdout.
Synopsis
Declared in <auto‐relates.cpp>
void
print(point p);
Description
The free function takes point as its only parameter, so it gets attached to point as a related function.
Parameters
Name |
Description |
p |
A two‐dimensional point. |
Function metadata
auto-function-metadata (on by default) fills in function documentation that authors typically omit because the result is mechanical or repetitive: the brief of a copy constructor, the parameter doc on operator==, the return value of a conversion operator. MrDocs writes the boilerplate so the hand-written comments can focus on what is actually unique to each function.
/// A 2D vector.
struct vec2
{
/// Construct from `x` and `y` components.
vec2(double x, double y);
vec2(vec2 const&);
vec2(vec2&&) noexcept;
~vec2();
vec2& operator=(vec2 const&);
bool operator==(vec2 const&) const;
/// Returns the Euclidean length of the vector.
double magnitude() const;
/// Translate this vector by `delta`.
vec2 translated(vec2 const& delta) const;
};
mrdocs.ymlauto-function-metadata: true
vec2
A 2D vector.
Synopsis
Declared in <auto‐function‐metadata.cpp>
struct vec2;
Member Functions
Name |
Description |
|
Construct from |
|
Destructor |
Copy assignment operator |
|
Returns the Euclidean length of the vector. |
|
Translate this vector by |
|
Equality operator |
vec2::vec2
Construct from x and y components.
Synopses
Declared in <auto‐function‐metadata.cpp>
Copy constructor
Move constructor
Construct from x and y components.
vec2(
double x,
double y);
vec2::vec2
Copy constructor
Synopsis
Declared in <auto‐function‐metadata.cpp>
vec2(vec2 const& other);
Parameters
Name |
Description |
other |
The object to copy construct from |
vec2::vec2
Move constructor
Synopsis
Declared in <auto‐function‐metadata.cpp>
vec2(vec2&& other) noexcept;
Parameters
Name |
Description |
other |
The object to move construct from |
vec2::vec2
Construct from x and y components.
Synopsis
Declared in <auto‐function‐metadata.cpp>
vec2(
double x,
double y);
Parameters
Name |
Description |
x |
The value to construct from |
vec2::~vec2
Destructor
Synopsis
Declared in <auto‐function‐metadata.cpp>
~vec2();
vec2::operator=
Copy assignment operator
Synopsis
Declared in <auto‐function‐metadata.cpp>
Return Value
Reference to the current object
Parameters
Name |
Description |
other |
The object to copy assign from |
vec2::magnitude
Returns the Euclidean length of the vector.
Synopsis
Declared in <auto‐function‐metadata.cpp>
double
magnitude() const;
Return Value
the Euclidean length of the vector.
vec2::translated
Translate this vector by delta.
Synopsis
Declared in <auto‐function‐metadata.cpp>
Return Value
A 2D vector.
Parameters
Name |
Description |
delta |
A 2D vector. |
vec2::operator==
Equality operator
Synopsis
Declared in <auto‐function‐metadata.cpp>
bool
operator==(vec2 const& rhs) const;
Return Value
true if the objects are equal, false otherwise
Parameters
Name |
Description |
rhs |
The right operand |
Several inferences in one example:
-
The copy and move constructors, the destructor, the copy assignment operator, and
operator==get full briefs ("Copy constructor", "Destructor", and so on) even though the source did not write one. -
None of those declarations name their parameter either, but MrDocs picks names from the function’s role:
otherfor the single-parameter constructors andoperator=,rhsfor the binaryoperator==. -
The parameter docs are filled the same way ("The object to copy construct from", "The right operand").
operator=andoperator==get return-value entries derived from their conventional contract ("Reference to the current object", "`true` if the objects are equal,falseotherwise"). -
vec2::magnitudehas only a brief in the source, but the brief begins with "Returns", so MrDocs lifts the rest of the sentence into the@returnentry. -
And
vec2::translated, an ordinary member function with only a brief, picks upvec2’s own brief ("A 2D vector.") for both its `deltaparameter and its return value, because no role-based rule applies and the type itself is documented.
Inherited members
When a class inherits from another, inherit-base-members determines how the inherited members should appear in the documentation.
never: The strictest setting lists the base relationship but does not repeat the base’s members on the derived page. This is the style used by cppreference. Readers follow the link to the base to see what they inherited:
/// A drawable shape.
struct shape
{
/// Render the shape.
void draw();
};
/// A circle.
struct circle : shape
{
/// Construct a circle of the given radius.
explicit circle(double r);
};
mrdocs.ymlinherit-base-members: never
circle
A circle.
Synopsis
Declared in <inherited‐members‐never.cpp>
struct circle
: shape
Base Classes
Name |
Description |
A drawable shape. |
Member Functions
Name |
Description |
|
Construct a circle of the given radius. |
circle::circle
Construct a circle of the given radius.
Synopsis
Declared in <inherited‐members‐never.cpp>
explicit
circle(double r);
Parameters
Name |
Description |
r |
The value to construct from |
shape
A drawable shape.
Synopsis
Declared in <inherited‐members‐never.cpp>
struct shape;
Member Functions
Name |
Description |
Render the shape. |
Derived Classes
Name |
Description |
A circle. |
shape::draw
Render the shape.
Synopsis
Declared in <inherited‐members‐never.cpp>
void
draw();
circle's page lists only its own constructor. The inherited draw is reachable through the link to shape. This is the model cppreference uses for the standard library. Technically correct, but most library docs do not want it: a reader landing on circle has to chase a link to find out what they can call on it.
reference: lists the inherited members directly on the derived class’s page. Each entry links back to the member of the base class, so the base class is the source of truth:
mrdocs.ymlinherit-base-members: reference
figure
A drawable figure.
Synopsis
Declared in <inherited‐members‐reference.cpp>
struct figure;
Member Functions
Name |
Description |
Render the figure. |
Derived Classes
Name |
Description |
A square. |
figure::draw
Render the figure.
Synopsis
Declared in <inherited‐members‐reference.cpp>
void
draw();
square
A square.
Synopsis
Declared in <inherited‐members‐reference.cpp>
struct square
: figure
Base Classes
Name |
Description |
A drawable figure. |
Member Functions
Name |
Description |
|
Construct a square of the given side. |
Render the figure. |
square::square
Construct a square of the given side.
Synopsis
Declared in <inherited‐members‐reference.cpp>
explicit
square(double side);
Parameters
Name |
Description |
side |
The value to construct from |
draw is now visible in circle's Member Functions table, alongside the constructor. Its link points at shape::draw, so there is no duplicate page. This is the natural choice when every base class lives in the corpus and has its own page.
copy-dependencies (the default) is meant to handle specializations more gracefully. The motivation for this option is that two patterns break the reference model:
-
Implicit template specializations.
class version: public detail::comparable<version>referencesdetail::comparable<version>, which the user did not write explicitly. MrDocs cannot point to a "see the base" link on a page that does not exist and creating a reference to the primary templatedetail::comparable<T>is not helpful because the reader cannot see the inherited members without following the link and mentally substitutingversionforT. -
Bases that are not in the corpus at all (a private detail header, an excluded vendor class, a system header). There is nowhere for the link to go.
In both cases, the reference option would leave the inherited members invisible or create a reference to a primary template that’s semantically hard to interpret. The default, copy-dependencies, behaves like reference when the base is already in the corpus. However, it uses the C++ compiler to actually instantiate the members for other cases, and copies the members of the instantiated base class into the derived page when the base is a dependency, so they are documented in place with the concrete operand types substituted in:
namespace detail {
/// CRTP base that lifts `compare()` into `operator==` and `operator!=`.
template <class T>
struct comparable
{
/// True if `compare()` is `0`.
bool operator==(T const& other) const noexcept;
/// True otherwise.
bool operator!=(T const& other) const noexcept;
};
}
/// A semantic version `(major, minor)`.
struct version : detail::comparable<version>
{
/// Construct from major and minor numbers.
version(int major, int minor) noexcept;
/// Three-way comparison against another version.
int compare(version const& other) const noexcept;
/// The major component.
int major;
/// The minor component.
int minor;
};
mrdocs.ymlinherit-base-members: copy-dependencies
implementation-defined:
- 'detail::**'
version
A semantic version (major, minor).
Synopsis
Declared in <inherited‐members‐specialization.cpp>
struct version
: /* implementation-defined */
Base Classes
Name |
Description |
|
CRTP base that lifts |
Member Functions
Name |
Description |
|
Construct from major and minor numbers. |
Three‐way comparison against another version. |
|
Equality operator |
|
Inequality operator |
Data Members
Name |
Description |
The major component. |
|
The minor component. |
version::version
Construct from major and minor numbers.
Synopsis
Declared in <inherited‐members‐specialization.cpp>
version(
int major,
int minor) noexcept;
Parameters
Name |
Description |
major |
The value to construct from |
version::compare
Three‐way comparison against another version.
Synopsis
Declared in <inherited‐members‐specialization.cpp>
int
compare(version const& other) const noexcept;
Parameters
Name |
Description |
other |
A semantic version |
version::operator==
Equality operator
Synopsis
Declared in <inherited‐members‐specialization.cpp>
bool
operator==(version const& other) const noexcept;
Return Value
true if the objects are equal, false otherwise
Parameters
Name |
Description |
other |
The right operand |
version::operator!=
Inequality operator
Synopsis
Declared in <inherited‐members‐specialization.cpp>
bool
operator!=(version const& other) const noexcept;
Return Value
true if the objects are not equal, false otherwise
Parameters
Name |
Description |
other |
The right operand |
version::major
The major component.
Synopsis
Declared in <inherited‐members‐specialization.cpp>
int major;
version::minor
The minor component.
Synopsis
Declared in <inherited‐members‐specialization.cpp>
int minor;
The configuration marks the detail namespace as implementation-defined, so neither the primary template detail::comparable nor any of its symbols have a page of their own and every reference to one of them renders as /* implementation-defined */. version's base class in the rendered synopsis is exactly that placeholder. The specialization detail::comparable<version> is therefore a pure dependency. copy-dependencies reaches into that instantiated base and copies its members onto version's page: operator== and operator!= appear in version's Member Functions table, with the parameter type rewritten to version const& and the boilerplate brief, parameter doc, and return value supplied by auto-function-metadata. The reader gets the full API of version in one place, with nothing referring outwardly to a base that has no page.
This is one of the larger gaps between MrDocs and other tools. Other tools could at most document the primary comparable<T> and report the inheritance, but the implicit specialization comparable<version> is not an entity that can be introspected without a compiler. The inherited operators silently disappear from version's page, and the Boost.Operators / CRTP idiom becomes invisible in the rendered docs. MrDocs treats the specialization as a first-class dependency and copies the resolved members into the derived class.
copy-all: The last possible setting copies every base member into every derived page, regardless of whether the base is in the corpus. It flattens the documentation: a reader on a derived page sees the full surface inline, with no need to follow base-class links. The price is duplication: the same member is documented on every class that inherits it.
Missing headers
The platform for a documentation build often doesn’t have the same dependencies and system libraries available. If a header is genuinely unavailable, the Migration Notes walk through the practical solutions. One of them is defining shims for these dependencies. The other options can be specified in the configuration file.
missing-include-shims lets you describe stub contents for individual headers directly in the configuration file (the key is the include path, the value is the file body MrDocs presents to the compiler):
missing-include-shims:
fmt/format.h: |
namespace fmt { template <class...> struct format_string {}; }
missing-include-prefixes tells MrDocs which include paths to forgive when they cannot be found, so the surrounding code parses anyway:
missing-include-prefixes:
- external/
Reach for these only when you need to. They are the answer to "MrDocs can’t find this header and I cannot install it"; if you can adjust the compilation database, that is the better path.