<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Enhancement: allow requires-clause checking of statement expression substitution success or failure"
   href="https://bugs.llvm.org/show_bug.cgi?id=46691">46691</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Enhancement: allow requires-clause checking of statement expression substitution success or failure
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++2a
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>wjwray@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>blitzrakete@gmail.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>SFINAE on structured bindings would provide a way to count the number
of bindings in a type at compile time (pending static reflection).
Knowing the count then allows to decompose any structured-bindable type.

SFINAE can only test expressions.
To check a structured binding statement it has to be wrapped as a
statement expression (non standard gnu extension in C++, from C).

This is a request to consider allowing checking of statement expressions
within requires clauses (probably limited to local function scope only)
as an enhancement.

Checking in requires clauses seems like the most direct approach:
<a href="https://godbolt.org/z/sM51f5">https://godbolt.org/z/sM51f5</a>

    template <typename T> constexpr int arity()
    {
           if constexpr (requires (T& a) { ({auto [x] = a;}); })   return 1;
      else if constexpr (requires (T& a) { ({auto [x,y] = a;}); }) return 2;
      //   ... etc ... 3,4,5 ... N
      else
           return 0;
    };

Clang accepts the template but fails all requires clauses to always return 0.

Clang since v5 already apparently allows statement-expression SFINAE
in trailing return type <a href="https://godbolt.org/z/YYPbvq">https://godbolt.org/z/YYPbvq</a>:

  template <typename T> auto arity_impl() {
    return overloads{
      [](auto&& u,int) -> decltype(({auto&& [x] = u; &"";})) {return {};},
      [](auto&& u,int) -> decltype(({auto&& [x,y] = u; &"2";})) {return {};},
      ...
      [](auto&& u,unsigned) -> void {}
    }(declval<T>(),int{});
  }

(the check can be done in default argument to Clang 10, broken on 11 trunk)

So, there's a solution to this in Clang since v5, but on shakey ground.
I know of no solution in GCC so I've made a similar enhancement request
<a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96170">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96170</a>

It seems that Clang is close to this already, so hopefully a small change.

Thanks for your considerations.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>