Open mpusz opened 4 years ago
Possibly support needs to be provided in Sphinx.
Patches are as always very welcome, there is a shortage of contributors.
I will do my best, but as I wrote in another thread I suck in Python ;-)
@melvinvermeeren is correct, Sphinx does not yet support requires clauses or requires expressions, so please open an issue over there (perhaps one for each, as they don't overlap in implementation anyway). As with most features, they are mostly implemented when someone needs them, so it would be great if you can provide examples so we can aim at making them work first.
Done: sphinx-doc/sphinx#7295, sphinx-doc/sphinx#7296.
You can find a lot of examples in my repo https://github.com/mpusz/units and its docs https://mpusz.github.io/units/index.html. For example this file: https://github.com/mpusz/units/blob/master/src/include/units/quantity.h.
Regarding requires clauses and https://github.com/sphinx-doc/sphinx/issues/7295#issuecomment-629810549. I just tried a small example:
template<Quantity To, typename D, typename U, typename Rep>
[[nodiscard]] constexpr auto quantity_cast(const quantity<D, U, Rep>& q) requires QuantityOf<To, D>;
and with Doxygen 1.8.13 the problem is definitely in the generated XML:
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.8.13">
<compounddef id="test_8hpp" kind="file" language="C++">
<compoundname>test.hpp</compoundname>
<sectiondef kind="var">
<memberdef kind="variable" id="test_8hpp_1a948d5c478709883883d2719721a89997" prot="public" static="no" mutable="no">
<type>constexpr auto</type>
<definition>constexpr auto D</definition>
<argsstring></argsstring>
<name>D</name>
...
</memberdef>
</sectiondef>
<sectiondef kind="func">
<memberdef kind="function" id="test_8hpp_1a08bd15b592e647dd1a08c72c45d51934" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
<templateparamlist>
<param>
<type>Quantity</type>
<declname>To</declname>
<defname>To</defname>
</param>
<param>
<type>typename D</type>
</param>
<param>
<type>typename U</type>
</param>
<param>
<type>typename Rep</type>
</param>
</templateparamlist>
<type>constexpr auto</type>
<definition>constexpr auto quantity_cast</definition>
<argsstring>(const quantity< D, U, Rep > &q) requires QuantityOf< To</argsstring>
<name>quantity_cast</name>
<param>
<type>const quantity< D, U, Rep > &</type>
<declname>q</declname>
</param>
...
</memberdef>
</sectiondef>
...
</compounddef>
</doxygen>
The missing part of the requires clause has been put into an extra variable declaration constexpr auto D
.
Perhaps a newer version gives a different result?
This is what I get for doxygen 1.8.17:
<memberdef kind="function" id="namespaceunits_1aa6c00f741adb967299312a654a577e5a" prot="public" static="no" constexpr="yes" const="no" explicit="no" inline="no" virt="non-virtual">
<templateparamlist>
<param>
<type>Quantity</type>
<declname>To</declname>
<defname>To</defname>
</param>
<param>
<type>typename D</type>
</param>
<param>
<type>typename U</type>
</param>
<param>
<type>typename Rep</type>
</param>
</templateparamlist>
<type>constexpr auto</type>
<definition>constexpr auto units::quantity_cast</definition>
<argsstring>(const quantity< D, U, Rep > &q) requires QuantityOf< To</argsstring>
<name>quantity_cast</name>
<param>
<type>const <ref refid="classunits_1_1quantity" kindref="compound">quantity</ref>< <ref refid="namespaceunits_1a84ee9cdfe11d0020084425cfceeda170" kindref="member">D</ref>, <ref refid="namespaceunits_1a36638878b7fc0a8fd9a238d36c6f107b" kindref="member">U</ref>, Rep > &</type>
<declname>q</declname>
</param>
<briefdescription>
<para>Explcit cast of a quantity. </para>
</briefdescription>
<detaileddescription>
<para>Implicit conversions between quantities of different types are allowed only for "safe" (i.e. non-truncating) conversion. In such cases an explicit cast have to be used.</para>
<para>This cast gets the target quantity type to cast to. For example:</para>
<para>auto q1 = <ref refid="namespaceunits_1aa6c00f741adb967299312a654a577e5a" kindref="member">units::quantity_cast</ref><<ref refid="namespaceunits_1_1physical_1_1si_1a86ff4b46eedd5d0bef7d950b762d957b" kindref="member">units::physical::si::time<units::physical::si::second></ref>>(1q_ms);</para>
<para><parameterlist kind="templateparam"><parameteritem>
<parameternamelist>
<parametername>To</parametername>
</parameternamelist>
<parameterdescription>
<para>a target quantity type to cast to</para>
</parameterdescription>
</parameteritem>
</parameterlist>
Implicit conversions between quantities of different types are allowed only for "safe" (i.e. non-truncating) conversion. In such cases an explicit cast have to be used.</para>
<para>This cast gets only the target dimension to cast to. For example:</para>
<para>auto q1 = units::quantity_cast<units::physical::si::acceleration>(200q_Gal);</para>
<para><parameterlist kind="templateparam"><parameteritem>
<parameternamelist>
<parametername>ToD</parametername>
</parameternamelist>
<parameterdescription>
<para>a dimension type to use for a target quantity</para>
</parameterdescription>
</parameteritem>
</parameterlist>
Implicit conversions between quantities of different types are allowed only for "safe" (i.e. non-truncating) conversion. In such cases an explicit cast have to be used.</para>
<para>This cast gets only the target unit to cast to. For example:</para>
<para>auto q1 = units::quantity_cast<units::physical::si::second>(1q_ms);</para>
<para><parameterlist kind="templateparam"><parameteritem>
<parameternamelist>
<parametername>ToU</parametername>
</parameternamelist>
<parameterdescription>
<para>a unit type to use for a target quantity</para>
</parameterdescription>
</parameteritem>
</parameterlist>
Implicit conversions between quantities of different types are allowed only for "safe" (i.e. non-truncating) conversion. In such cases an explicit cast have to be used.</para>
<para>This cast gets only representation to cast to. For example:</para>
<para>auto q1 = units::quantity_cast<int>(1q_ms);</para>
<para><parameterlist kind="templateparam"><parameteritem>
<parameternamelist>
<parametername>ToRep</parametername>
</parameternamelist>
<parameterdescription>
<para>a representation type to use for a target quantity </para>
</parameterdescription>
</parameteritem>
</parameterlist>
</para>
</detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/mpusz/repos/units/src/include/units/quantity_cast.h" line="328" column="17" bodyfile="/home/mpusz/repos/units/src/include/units/quantity_cast.h" bodystart="390" bodyend="393"/>
</memberdef>
for the following code:
I just tried with Doxygen 1.8.18 as well, and it gives the same result: the <argsstring>
is incomplete and stops in the middle of the requires-clause. So I don't think Breathe can do any better for now.
Upstream issue to track: https://github.com/doxygen/doxygen/issues/2732
Edit: see examples there for possible workarounds documenting them as interfaces.
As I understand the workaround is for concepts definitions and does not apply to requires clauses?
Please provide support for C++20 requires clauses and requires expressions.