Skip to content

Commit 7ee2a4e

Browse files
committed
feat: render dependent noexcept specifications as noexcept(see-below)
MrDocs used to render the full `noexcept` operand inline, so a declaration like void swap(reference, reference) noexcept( std::is_nothrow_move_constructible<value_t>::value && std::is_nothrow_move_assignable<value_t>::value && std::is_nothrow_move_constructible<json_value>::value && std::is_nothrow_move_assignable<json_value>::value); buried the `noexcept` condition in a mostly-unreadable slop. This replaces dependent operands with an italic "see-below" placeholder in the declaration, and moves the actual condition to a dedicated "noexcept Specification" section of the exposition: void swap(reference, reference) noexcept(see-below); === noexcept Specification noexcept when `...long condition...`. The section is intentionally separate from the existing "Exceptions" section, which continues to cover `@throws` documentation. Closes issue #1103.
1 parent 0246935 commit 7ee2a4e

24 files changed

Lines changed: 636 additions & 36 deletions

File tree

include/mrdocs/Metadata/Specifiers/NoexceptInfo.hpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <mrdocs/Metadata/Specifiers/ExplicitInfo.hpp>
1919
#include <mrdocs/Metadata/Specifiers/ExplicitKind.hpp>
2020
#include <mrdocs/Metadata/Specifiers/NoexceptKind.hpp>
21+
#include <mrdocs/Support/Describe.hpp>
2122
#include <string>
2223

2324
namespace mrdocs {
@@ -43,6 +44,11 @@ struct NoexceptInfo
4344
auto operator<=>(NoexceptInfo const&) const = default;
4445
};
4546

47+
MRDOCS_DESCRIBE_STRUCT(
48+
NoexceptInfo,
49+
(),
50+
(Implicit, Kind, Operand))
51+
4652
/** Convert NoexceptInfo to a string.
4753
4854
@param info The noexcept-specifier information.
@@ -62,18 +68,6 @@ toString(
6268
bool resolved = false,
6369
bool implicit = false);
6470

65-
/** Convert a NoexceptInfo to a DOM value.
66-
*/
67-
inline
68-
void
69-
tag_invoke(
70-
dom::ValueFromTag tag,
71-
dom::Value& v,
72-
NoexceptInfo const& info)
73-
{
74-
v = toString(info, false, false);
75-
}
76-
7771
} // mrdocs
7872

7973
#endif

include/mrdocs/Metadata/Specifiers/NoexceptKind.hpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
#define MRDOCS_API_METADATA_SPECIFIERS_NOEXCEPTKIND_HPP
1414

1515
#include <mrdocs/Platform.hpp>
16-
#include <mrdocs/Dom/String.hpp>
17-
#include <string>
16+
#include <mrdocs/Support/Describe.hpp>
1817

1918
namespace mrdocs {
2019

@@ -33,11 +32,7 @@ enum class NoexceptKind
3332
Dependent
3433
};
3534

36-
/** Convert a noexcept kind to its string form.
37-
*/
38-
MRDOCS_DECL
39-
dom::String
40-
toString(NoexceptKind kind) noexcept;
35+
MRDOCS_DESCRIBE_ENUM(NoexceptKind, False, True, Dependent)
4136

4237
} // mrdocs
4338

mrdocs.rnc

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,23 @@ grammar
9595

9696
TableAlignmentKind = "left" | "center" | "right"
9797

98+
NoexceptKind = "false" | "true" | "dependent"
99+
100+
#---------------------------------------------
101+
# noexcept specification
102+
#
103+
# Emitted only when a noexcept-specifier is user-written
104+
# (implicit specifications are skipped). The operand holds
105+
# the expression as written, when present.
106+
#---------------------------------------------
107+
108+
NoexceptSpec =
109+
element noexcept
110+
{
111+
element kind { NoexceptKind },
112+
element operand { text }?
113+
}
114+
98115
#---------------------------------------------
99116
# Name (used inside types, not for symbol names)
100117
#---------------------------------------------
@@ -187,7 +204,7 @@ grammar
187204
TypeBase,
188205
AnyType*,
189206
element ref-qualifier { text }?,
190-
element exception-spec { text }?,
207+
NoexceptSpec?,
191208
element is-variadic { Bool }?
192209
}
193210

@@ -420,7 +437,7 @@ grammar
420437
Param*,
421438
TemplateInfo?,
422439
element func-class { FunctionClass }?,
423-
element noexcept { text }?,
440+
NoexceptSpec?,
424441
element requires { text }?,
425442
element is-variadic { Bool }?,
426443
element is-defaulted { Bool }?,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pass:q[_see-below_]

share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,16 @@
167167
| {{> symbol/qualified-name . }}
168168
{{/each}}
169169
|===
170+
{{/if}}
171+
{{/if}}
172+
{{! noexcept specification — only for dependent operands; constant
173+
expressions like noexcept(true)/noexcept(false) are shown inline
174+
in the signature and need no separate section. }}
175+
{{#if (eq symbol.noexcept.kind "dependent")}}
176+
{{#if symbol.noexcept.operand}}
177+
{{#> markup/dynamic-level-h }}noexcept Specification{{/markup/dynamic-level-h~}}
178+
`noexcept` when `{{symbol.noexcept.operand}}`.
179+
170180
{{/if}}
171181
{{/if}}
172182
{{! Exceptions }}

share/mrdocs/addons/generator/common/partials/symbol/signature/function.hbs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
{{~#if isConst}} const{{/if~}}
3232
{{#if isVolatile}} volatile{{/if~}}
3333
{{#if refQualifier}} {{refQualifier}}{{/if~}}
34-
{{#if noexcept}} {{noexcept}}{{/if~}}
34+
{{~#unless noexcept.implicit~}}
35+
{{~#if (eq noexcept.kind "dependent")}} noexcept({{> markup/see-below }}){{else if noexcept.operand}} noexcept({{noexcept.operand}}){{else if (eq noexcept.kind "true")}} noexcept{{/if~}}
36+
{{~/unless~}}
3537
{{#if (eq funcClass "normal")}}{{>type/declarator-suffix returnType}}{{/if~}}
3638
{{#if requires}}
3739

share/mrdocs/addons/generator/common/partials/type/declarator-suffix.hbs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@
3737
{{~#if cv-qualifiers}} {{cv-qualifiers}}{{/if~}}
3838
{{! Refqualifiers as "&" or "&&" ~}}
3939
{{#if (eq refQualifier "lvalue")}} &{{else if (eq refQualifier "rvalue")}} &&{{/if~}}
40-
{{! Exception spec as literal string ~}}
41-
{{#if exceptionSpec}} {{exceptionSpec}}{{/if~}}
40+
{{! noexcept specification with "see-below" placeholder for dependent operands ~}}
41+
{{~#unless exceptionSpec.implicit~}}
42+
{{~#if (eq exceptionSpec.kind "dependent")}} noexcept({{> markup/see-below }}){{else if exceptionSpec.operand}} noexcept({{exceptionSpec.operand}}){{else if (eq exceptionSpec.kind "true")}} noexcept{{/if~}}
43+
{{~/unless~}}
4244
{{! Declarator suffix of the return type ~}}
4345
{{~>type/declarator-suffix returnType link-components-impl=link-components-impl~}}
4446
{{/if}}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<em>see-below</em>

share/mrdocs/addons/generator/html/partials/symbol.html.hbs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,17 @@
231231
{{/if}}
232232
</div>
233233

234+
{{/if}}
235+
{{! noexcept specification — only for dependent operands; constant
236+
expressions like noexcept(true)/noexcept(false) are shown inline
237+
in the signature and need no separate section. }}
238+
{{#if (eq symbol.noexcept.kind "dependent")}}
239+
{{#if symbol.noexcept.operand}}
240+
<div>
241+
{{#> markup/dynamic-level-h level=2 }}noexcept Specification{{/markup/dynamic-level-h~}}
242+
<p><code>noexcept</code> when <code>{{symbol.noexcept.operand}}</code>.</p>
243+
</div>
244+
{{/if}}
234245
{{/if}}
235246
{{! Exceptions }}
236247
{{#if symbol.doc.exceptions}}

src/lib/Gen/xml/XMLWriter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "XMLWriter.hpp"
1616
#include <mrdocs/Metadata/Expression.hpp>
17+
#include <mrdocs/Metadata/Specifiers/NoexceptInfo.hpp>
1718
#include <mrdocs/Metadata/Type.hpp>
1819
#include <mrdocs/Metadata/Template.hpp>
1920
#include <mrdocs/Metadata/DocComment.hpp>
@@ -180,6 +181,8 @@ XMLWriter::writeElement(std::string_view tag, T const& value)
180181
{ if (value.empty()) return; }
181182
else if constexpr (std::is_base_of_v<ExprInfo, Type>)
182183
{ if (value.Written.empty()) return; }
184+
else if constexpr (std::is_same_v<Type, NoexceptInfo>)
185+
{ if (value.Implicit) return; }
183186

184187
// Primitives inline, compounds wrapped.
185188
if constexpr (std::is_base_of_v<ExprInfo, Type>)

0 commit comments

Comments
 (0)