Skip to content

Instantly share code, notes, and snippets.

@matovitch
Last active December 8, 2023 10:03
Show Gist options
  • Save matovitch/5dfdac845b159b6a0a8e to your computer and use it in GitHub Desktop.
Save matovitch/5dfdac845b159b6a0a8e to your computer and use it in GitHub Desktop.
#ifndef __VISITOR_HPP__
#define __VISITOR_HPP__
template<typename... Types>
struct Visitor;
template<typename... Visitors>
struct Visitable;
template<typename T>
struct Visitor<T>
{
virtual void visit(T & visitable) = 0;
};
template<typename T, typename... Types>
struct Visitor<T, Types...> : public Visitor<Types...>
{
using Visitor<Types...>::visit;
virtual void visit(T & visitable) = 0;
};
template<typename V>
struct Visitable<V>
{
virtual void accept(V& visitor) = 0;
};
template<typename Derived, typename V>
struct Visitable<Derived, V> : Visitable<V>
{
virtual void accept(V& visitor)
{
visitor.visit(dynamic_cast<Derived&>(*this));
}
};
template<typename Derived, typename V, typename... Visitors>
struct Visitable<Derived, V, Visitors...> : public Visitable<Derived, Visitors...>, Visitable<V>
{
using Visitable<Derived, Visitors...>::accept;
virtual void accept(V& visitor)
{
visitor.visit(static_cast<Derived&>(*this));
}
};
#endif // end __VISITOR_HPP__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment