Skip to content

Commit 4fa1508

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 4fa1508

36 files changed

Lines changed: 840 additions & 103 deletions

include/mrdocs/Metadata/Specifiers/ExplicitInfo.hpp

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

1515
#include <mrdocs/Platform.hpp>
1616
#include <mrdocs/Metadata/Specifiers/ExplicitKind.hpp>
17+
#include <mrdocs/Support/Describe.hpp>
1718
#include <string>
1819

1920
namespace mrdocs {
@@ -27,7 +28,7 @@ struct ExplicitInfo
2728
{
2829
/** Whether an explicit-specifier was user-written.
2930
*/
30-
bool Implicit = true;
31+
bool IsUserWritten = false;
3132

3233
/** The evaluated exception specification.
3334
*/
@@ -42,6 +43,11 @@ struct ExplicitInfo
4243
auto operator<=>(ExplicitInfo const&) const = default;
4344
};
4445

46+
MRDOCS_DESCRIBE_STRUCT(
47+
ExplicitInfo,
48+
(),
49+
(IsUserWritten, Kind, Operand))
50+
4551
/** Convert ExplicitInfo to a string.
4652
4753
@param info The explicit-specifier information.
@@ -57,21 +63,6 @@ toString(
5763
bool resolved = false,
5864
bool implicit = false);
5965

60-
/** Return the ExplicitInfo as a @ref dom::Value string.
61-
62-
@param v The output parameter to receive the dom::Value.
63-
@param I The ExplicitInfo to convert.
64-
*/
65-
inline
66-
void
67-
tag_invoke(
68-
dom::ValueFromTag,
69-
dom::Value& v,
70-
ExplicitInfo const& I)
71-
{
72-
v = toString(I);
73-
}
74-
7566
} // mrdocs
7667

7768
#endif

include/mrdocs/Metadata/Specifiers/ExplicitKind.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_EXPLICITKIND_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 ExplicitKind
3332
Dependent
3433
};
3534

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

4237
} // mrdocs
4338

include/mrdocs/Metadata/Specifiers/NoexceptInfo.hpp

Lines changed: 7 additions & 13 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 {
@@ -28,7 +29,7 @@ struct NoexceptInfo
2829
{
2930
/** Whether a noexcept-specifier was user-written.
3031
*/
31-
bool Implicit = true;
32+
bool IsUserWritten = false;
3233

3334
/** The evaluated exception specification.
3435
*/
@@ -43,6 +44,11 @@ struct NoexceptInfo
4344
auto operator<=>(NoexceptInfo const&) const = default;
4445
};
4546

47+
MRDOCS_DESCRIBE_STRUCT(
48+
NoexceptInfo,
49+
(),
50+
(IsUserWritten, 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

include/mrdocs/Support/MergeReflectedType.hpp

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,12 @@ isPlaceholderType(Polymorphic<Type> const& t);
9595
4. `Polymorphic<Type>` — take if placeholder (AutoType or blank
9696
NamedType)
9797
5. `Polymorphic<Name>` — take if Identifier is empty
98-
6. `.Implicit` types — take if dst is implicit
99-
7. `Optional<T>` — take if disengaged; recursive merge
98+
6. `Optional<T>` — take if disengaged; recursive merge
10099
if both engaged and T has `merge()`
101-
8. `enum` — take if zero-initialized
102-
9. `string` — take if empty
103-
10. `vector<T>` with `==` — dedup-append
104-
11. `vector<T>` fallback — take if dst is empty
100+
7. `enum` — take if zero-initialized
101+
8. `string` — take if empty
102+
9. `vector<T>` with `==` — dedup-append
103+
10. `vector<T>` fallback — take if dst is empty
105104
106105
Returns `false` only for types none of the above handles.
107106
*/
@@ -152,16 +151,6 @@ mergeByType(T& dst, T&& src)
152151
}
153152
return true;
154153
}
155-
// Types with .Implicit flag (NoexceptInfo, ExplicitInfo):
156-
// take src if dst is still implicit (compiler-generated).
157-
else if constexpr (requires(T const& t) { { t.Implicit } -> std::convertible_to<bool>; })
158-
{
159-
if (dst.Implicit)
160-
{
161-
dst = std::move(src);
162-
}
163-
return true;
164-
}
165154
// Optional<T>: take if disengaged; recursive merge if both
166155
// engaged and the value type has a merge() function.
167156
else if constexpr (is_optional_v<T>)

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: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
{{/if~}}
1111
{{#if isVirtual}}virtual
1212
{{/if~}}
13-
{{#if explicit}}{{explicit}}
13+
{{#if explicit.isUserWritten}}
14+
{{~#if explicit.operand}}explicit({{explicit.operand}}){{else if (eq explicit.kind "true")}}explicit{{/if}}
1415
{{/if~}}
1516
{{#if (eq funcClass "normal")}}{{>type/declarator-prefix returnType}}
1617
{{/if~}}
@@ -31,7 +32,9 @@
3132
{{~#if isConst}} const{{/if~}}
3233
{{#if isVolatile}} volatile{{/if~}}
3334
{{#if refQualifier}} {{refQualifier}}{{/if~}}
34-
{{#if noexcept}} {{noexcept}}{{/if~}}
35+
{{~#if noexcept.isUserWritten~}}
36+
{{~#if (eq noexcept.kind "dependent")}} noexcept({{> markup/see-below }}){{else if noexcept.operand}} noexcept({{noexcept.operand}}){{else if (eq noexcept.kind "true")}} noexcept{{/if~}}
37+
{{~/if~}}
3538
{{#if (eq funcClass "normal")}}{{>type/declarator-suffix returnType}}{{/if~}}
3639
{{#if requires}}
3740

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+
{{~#if exceptionSpec.isUserWritten~}}
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+
{{~/if~}}
4244
{{! Declarator suffix of the return type ~}}
4345
{{~>type/declarator-suffix returnType link-components-impl=link-components-impl~}}
4446
{{/if}}

0 commit comments

Comments
 (0)