Skip to content

Latest commit

 

History

History
115 lines (92 loc) · 2.88 KB

337.md

File metadata and controls

115 lines (92 loc) · 2.88 KB
Info

  • Did you know that run-time dispatching over type-list can be implemented many different ways?

Example

template <template <class...> class TList, class TEvent, class... TEvents, class T, class TExpr>
constexpr auto dispatch(TList<TEvent, TEvents...>, const int id, const T& data,
                        const TExpr& expr) -> decltype(expr(TEvent{data})) {
    switch (id) {
        case TEvent::id:
            return expr(TEvent{data});

        default:
            if constexpr (sizeof...(TEvents) > 0) {
                return dispatch(TList<TEvents...>{}, id, data, expr);
            }
    }
    return {};
}

https://godbolt.org/z/YzrTKsahd

Puzzle

  • Can you implement dispatch with the follwing methods?

    • if else
    • jump table
    • fold expressions
    • ...
template <template<class...> class TList, class TEvent, class... TEvents, class T, class TExpr>
constexpr auto dispatch(TList<TEvent, TEvents...>, const int id, const T& data, const TExpr& expr) {
  // TODO if else
  return 0;
}

https://godbolt.org/z/xcoEe89nf

template <class... TEvents, class T, class TExpr>
constexpr auto dispatch(const int id, const T& data, const TExpr& expr) {
  // TODO jump table
  return 0;
}

https://godbolt.org/z/W4c49Mx34

template <class... TEvents, class T, class TExpr>
constexpr auto dispatch(const int id, const T& data, const TExpr& expr) {
  // TODO fold expressions
  return 0;
}

https://godbolt.org/z/9GzW4sYon

Solutions

template <template <class...> class TList, class TEvent, class... TEvents,
          class T, class TExpr>
constexpr auto dispatch(TList<TEvent, TEvents...>, const int id, const T& data,
                        const TExpr& expr) -> decltype(expr(TEvent{data})) {
    // if else
    if (id == TEvent::id) {
        return expr(TEvent{data});
    } else if constexpr (sizeof...(TEvents) > 0) {
        return dispatch(TList<TEvents...>{}, id, data, expr);
    }
    return 0;
}

https://godbolt.org/z/68Kq8sd4K

template <class... TEvents, class T, class TExpr>
constexpr auto dispatch(const int id, const T& data, const TExpr& expr) {
    // jump table
    const auto jump_table = [expr](TEvents... events) {
        return std::array{(expr(events))...};
    }(TEvents{data}...);
    return jump_table[id];
}

https://godbolt.org/z/7fec111dG

template <class... TEvents, class T, class TExpr>
constexpr auto dispatch(const int id, const T& data, const TExpr& expr) {
    // fold expressions
    return ([&](auto&& event) {
        if (id == event.id) {
            return expr(event);
        }
        return 0;
    }(TEvents{data}) +
            ...);
}

https://godbolt.org/z/GzfPerde5