Update variant
"all types same/convertible" metaprogramming
#3070
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
And a few other minor changes while we're here. I've separated changes out by commit for ease of review, but this should be squash merged. The most significant change here - others are self-explanatory - replaces the metaprogramming used to enforce the Standard's requirements that "For each valid pack m, e(m) is a valid expression. All such expressions are of the same type
and value category" ([variant.visit]/5).
here are different mechanisms to validate the requirement for
visit<R>
and for plainvisit
. Previously, we created a single typelist where each type represented one possible configuration of the set of argument variants to a visit call, and then folded over a single giant pack expansion of visitor evaluations ensuring they had the same type and value category (or are all convertible toR
forvisit<R>
). This was enormously expensive for throughput when the number of possible states is large since the compilers burn a lot of memory maintaining long typelists. The new version uses tree evaluation, where each internal node of the treeand
s together the result of evaluating its child nodes, which each correspond to a possible state of a single argument variant. Leaves correspond to potential calls and have a boolean value indicating whether that potential call has the same type and value category as the first valid configuration (has a type and value category convertible to the result type forvisit<R>
).The resulting speedup for the long-pole
/analyze
configs of thevisit
tests in the "Update LLVM" PR is around 50%.Fixes #2770.
Unblocks #2976.