Awesome
visit
A fast, generalized, and not quite std conforming, version of
visit
for
variant
This is the implementation for the visit
written about in the blog post
When performance guarantees hurts performande - std::visit
The reason it is fast is because it does away with the requirement of O(1) lookup, essentially requiring calls through function pointers, and instead allows perfect inlining through a series of if/else, which the compiler can optimise better.
It is generalized in the way that it supports parameters that are not variants,
and they are just forwarded to the visitor, as-is. All variant parameters are
forwarded as their current member (if any). It also handles types inheriting
from std::variant<>
as variants.
Example:
using V = std::variant<int, std::string>;
struct S : V
{
using V::V;
};
using P = std::unique_ptr<int>;
using std::to_string;
using std::string;
struct visitor {
auto operator()(int i1, P p, int i2) const { return to_string(i1) + to_string(*p) + to_string(i2); }
auto operator()(string s, P p, int i2) const { return s + to_string(*p) + to_string(i2); }
auto operator()(int i1, P p, string s) const { return to_string(i1) + to_string(*p) + s; }
auto operator()(string s1, P p, string s2) const { return s1 + to_string(*p) + s2; }
};
auto r = rollbear::visit(visitor{}, V{1}, std::make_unique<int>(3), S{string{"foo"}});
assert(r == "13foo");
See the test sources for more details.
A note on performance:
The overheads mentioned are tiny, and often other performance factors wil dominate. With that said,
the included benchmark program shows that, on my machines, rollbear::visit
is consistently faster
than std::visit
with clang compilers, regardless of whether using libc++
or libstdc++
.
With gcc compilers it varies with version, and std::visit
is typically faster for large variants
with many members, while rollbear::visit
is typically faster for variants with 8 or fewer members.
Measure to find out for your tools and your hardware.
See also Michael Park's variant with its visit. https://github.com/mpark/variant