ldionne/dyno

Add benchmarks against discriminated unions

ldionne opened this issue · 2 comments

As requested by @mavam.

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.

Closed by #18.