Skip to content

Commit

Permalink
support SFINAE via template arguments
Browse files Browse the repository at this point in the history
#feat
  • Loading branch information
alandefreitas committed Jan 22, 2025
1 parent 5de708b commit b885e2e
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 78 deletions.
49 changes: 49 additions & 0 deletions src/lib/AST/ASTVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,55 @@ populate(
{
populate(TI.Requires, RC);
}
else
{
// If there's no requires clause, check if the template
// parameter types we extracted have constraints
for (auto it = TI.Params.begin(); it != TI.Params.end(); )
{
std::unique_ptr<TParam>& param = *it;

if (auto const* T = dynamic_cast<NonTypeTParam*>(param.get());
T &&
T->Type &&
!T->Type->Constraints.empty())
{
for (ExprInfo const& constraint: T->Type->Constraints)
{
if (!TI.Requires.Written.empty())
{
TI.Requires.Written += " && ";
}
TI.Requires.Written += constraint.Written;
}
it = TI.Params.erase(it);
continue;
}

if (param->Default &&
param->Default->isType())
{
if (auto const* T = dynamic_cast<TypeTArg*>(param->Default.get());
T &&
T->Type &&
!T->Type->Constraints.empty())
{
for (ExprInfo const& constraint: T->Type->Constraints)
{
if (!TI.Requires.Written.empty())
{
TI.Requires.Written += " && ";
}
TI.Requires.Written += constraint.Written;
}
it = TI.Params.erase(it);
continue;
}
}

++it;
}
}
}

void
Expand Down
41 changes: 18 additions & 23 deletions test-files/golden-tests/metadata/sfinae.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
| <<A-09,`A`>>
| The partial specialization of A is enabled via a template parameter

| <<A-02,`A&lt;T, void&gt;`>>
| <<A-02,`A&lt;T&gt;`>>
| Specialization for floating point types

| <<S-02,`S`>>
Expand Down Expand Up @@ -123,7 +123,7 @@ class A;


[#A-02]
== A&lt;T, void&gt;
== A&lt;T&gt;


Specialization for floating point types
Expand All @@ -136,7 +136,8 @@ Declared in `&lt;sfinae&period;cpp&gt;`
[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
template&lt;class T&gt;
class <<A-09,A>>&lt;T, void&gt;;
requires std&colon;&colon;is&lowbar;integral&lowbar;v&lt;T&gt;
class <<A-09,A>>&lt;T&gt;;
----


Expand All @@ -157,7 +158,7 @@ Declared in `&lt;sfinae&period;cpp&gt;`
----
template&lt;
class T,
class = void&gt;
class Enable = void&gt;
struct S;
----

Expand Down Expand Up @@ -261,11 +262,10 @@ Declared in `&lt;sfinae&period;cpp&gt;`

[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
template&lt;
class T,
typename = void&gt;
template&lt;class T&gt;
requires std&colon;&colon;is&lowbar;integral&lowbar;v&lt;T&gt;
void
f10(T* t);
f10(T value);
----

=== Description
Expand Down Expand Up @@ -346,9 +346,8 @@ Declared in `&lt;sfinae&period;cpp&gt;`

[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
template&lt;
class T,
bool = true&gt;
template&lt;class T&gt;
requires std&colon;&colon;is&lowbar;integral&lowbar;v&lt;T&gt;
T
f5(T value);
----
Expand All @@ -366,9 +365,8 @@ Declared in `&lt;sfinae&period;cpp&gt;`

[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
template&lt;
class T,
bool = true&gt;
template&lt;class T&gt;
requires std&colon;&colon;is&lowbar;integral&lowbar;v&lt;T&gt;
T
f6(T value);
----
Expand All @@ -386,9 +384,8 @@ Declared in `&lt;sfinae&period;cpp&gt;`

[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
template&lt;
class T,
int = 0&gt;
template&lt;class T&gt;
requires std&colon;&colon;is&lowbar;integral&lowbar;v&lt;T&gt;
void
f7(T value);
----
Expand All @@ -408,9 +405,8 @@ Declared in `&lt;sfinae&period;cpp&gt;`
----
template&lt;class T&gt;
T
f8(
T value,
void* = 0);
f8(T value)
requires std&colon;&colon;is&lowbar;integral&lowbar;v&lt;T&gt;;
----

[#f9]
Expand All @@ -428,9 +424,8 @@ Declared in `&lt;sfinae&period;cpp&gt;`
----
template&lt;class T&gt;
T
f9(
T value,
void* = 0);
f9(T value)
requires std&colon;&colon;is&lowbar;integral&lowbar;v&lt;T&gt;;
----


Expand Down
6 changes: 3 additions & 3 deletions test-files/golden-tests/metadata/sfinae.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ T
f6(T value);

/// Enabled via a non-type template parameter using int instead of bool
template<class T, std::enable_if_t<T::value1, int> = 0>
template<class T, std::enable_if_t<std::is_integral_v<T>, int> = 0>
void f7(T value);

/// Enabled via parameter without helper
Expand All @@ -62,7 +62,7 @@ f9(T value, std::enable_if_t<std::is_integral_v<T>>* = 0);
/// arguments are not accounted for in function template equivalence).
///
template<class T, typename = std::enable_if_t<std::is_integral_v<T>>>
void f10(T* t);
void f10(T value);

/// The partial specialization of A is enabled via a template parameter
template<class T, class Enable = void>
Expand All @@ -73,7 +73,7 @@ template<class T>
class A<T, std::enable_if_t<std::is_integral_v<T>>> {};

/// SFINAE with std::void_t
template <class T, class = void>
template <class T, class Enable = void>
struct S
{
void store(const void*) {}
Expand Down
41 changes: 18 additions & 23 deletions test-files/golden-tests/metadata/sfinae.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ <h2>Types</h2>
<td><a href="#A-09"><code>A</code></a> </td><td><span><span>The partial specialization of A is enabled via a template parameter</span></span>

</td></tr><tr>
<td><a href="#A-02"><code>A&lt;T, void&gt;</code></a> </td><td><span><span>Specialization for floating point types</span></span>
<td><a href="#A-02"><code>A&lt;T&gt;</code></a> </td><td><span><span>Specialization for floating point types</span></span>

</td></tr><tr>
<td><a href="#S-02"><code>S</code></a> </td><td><span><span>SFINAE with std::void_t</span></span>
Expand Down Expand Up @@ -147,7 +147,7 @@ <h3>Synopsis</h3>
</div>
<div>
<div>
<h2 id="A-02">A&lt;T, void&gt;</h2>
<h2 id="A-02">A&lt;T&gt;</h2>
<div>
<span><span>Specialization for floating point types</span></span>

Expand All @@ -161,7 +161,8 @@ <h3>Synopsis</h3>
<pre>
<code class="source-code cpp">
template&lt;class T&gt;
class <a href="#A-09">A</a>&lt;T, void&gt;;
requires std::is_integral_v&lt;T&gt;
class <a href="#A-09">A</a>&lt;T&gt;;
</code>
</pre>
</div>
Expand All @@ -185,7 +186,7 @@ <h3>Synopsis</h3>
<code class="source-code cpp">
template&lt;
class T,
class = void&gt;
class Enable = void&gt;
struct S;
</code>
</pre>
Expand Down Expand Up @@ -309,11 +310,10 @@ <h3>Synopsis</h3>
Declared in <code>&lt;sfinae.cpp&gt;</code></div>
<pre>
<code class="source-code cpp">
template&lt;
class T,
typename = void&gt;
template&lt;class T&gt;
requires std::is_integral_v&lt;T&gt;
void
f10(T* t);
f10(T value);
</code>
</pre>
</div>
Expand Down Expand Up @@ -407,9 +407,8 @@ <h3>Synopsis</h3>
Declared in <code>&lt;sfinae.cpp&gt;</code></div>
<pre>
<code class="source-code cpp">
template&lt;
class T,
bool = true&gt;
template&lt;class T&gt;
requires std::is_integral_v&lt;T&gt;
T
f5(T value);
</code>
Expand All @@ -431,9 +430,8 @@ <h3>Synopsis</h3>
Declared in <code>&lt;sfinae.cpp&gt;</code></div>
<pre>
<code class="source-code cpp">
template&lt;
class T,
bool = true&gt;
template&lt;class T&gt;
requires std::is_integral_v&lt;T&gt;
T
f6(T value);
</code>
Expand All @@ -455,9 +453,8 @@ <h3>Synopsis</h3>
Declared in <code>&lt;sfinae.cpp&gt;</code></div>
<pre>
<code class="source-code cpp">
template&lt;
class T,
int = 0&gt;
template&lt;class T&gt;
requires std::is_integral_v&lt;T&gt;
void
f7(T value);
</code>
Expand All @@ -481,9 +478,8 @@ <h3>Synopsis</h3>
<code class="source-code cpp">
template&lt;class T&gt;
T
f8(
T value,
void* = 0);
f8(T value)
requires std::is_integral_v&lt;T&gt;;
</code>
</pre>
</div>
Expand All @@ -505,9 +501,8 @@ <h3>Synopsis</h3>
<code class="source-code cpp">
template&lt;class T&gt;
T
f9(
T value,
void* = 0);
f9(T value)
requires std::is_integral_v&lt;T&gt;;
</code>
</pre>
</div>
Expand Down
Loading

0 comments on commit b885e2e

Please sign in to comment.