Add benchmarks against discriminated unions
ldionne opened this issue · 2 comments
mavam commented
Here's an untested/uncompiled strawman to be included in the any_iterator
benchmarks:
namespace { namespace variant {
template <typename Derived>
struct concept_t {
friend bool operator==(Derived const& a, Derived const& b) {
return a.equal(b);
}
Derived& operator++() {
static_cast<Derived*>(this)->increment();
return *this;
}
decltype(auto) operator*() {
return static_cast<Derived*>(this)->dereference();
}
};
template <typename Iterator>
struct model_t : concept_t<Iterator> {
model_t(Iterator it) : it_{it} { }
bool equal(model_t const& other) { return it_ == other.it_; }
void increment() { ++it_; }
typename Iterator::reference dereference() { return *it_; }
private:
Iterator it_;
}
template <typename... Ts>
struct variant {
// TODO: implement
};
template <typename F f, typename T>
decltype(auto) visit(F&&, T&& x) {
// TODO: apply f(x)
}
template <typename... Ts>
using iterator_variant = variant<model_t<Ts>...>;
template <typename Value, typename Reference = Value&>
struct any_iterator : concept_t<any_iterator<Value, Reference>> {
using value_type = Value;
using reference = Reference;
template <typename Iterator>
explicit any_iterator(Iterator it)
: v_{model_t<Iterator>{it}}
{ }
bool equal(any_iterator const& other) {
return v_ == other.v_; // relies on variant<Ts>::operator==
}
void increment() {
visit([](auto& x) { ++x; }, v_);
}
Reference dereference() {
return visit([](auto& x) { *x; }, v_);
}
private:
iterator_variant<Value> v_;
};
}} // end namespace variant
I hope that goes in the right direction. It's a bit quirky because unlike the other approaches to type-erasure, the variant is bounded a priori. So the corresponding any_iterator
is a bit clunky: right now it only holds one value.