2015-12-08 04:51:55 +08:00
|
|
|
#pragma once
|
2015-08-30 07:12:46 +08:00
|
|
|
|
|
|
|
namespace detail
|
|
|
|
{
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
struct VisitorBase {
|
2015-10-19 01:44:00 +08:00
|
|
|
virtual ~VisitorBase() = default;
|
2015-08-30 07:12:46 +08:00
|
|
|
|
|
|
|
virtual void visit(T&) {}
|
|
|
|
virtual void post_visit(T&) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename... T>
|
|
|
|
struct RecursiveVisitorBase;
|
|
|
|
|
|
|
|
template <typename Head, typename... Tail>
|
|
|
|
struct RecursiveVisitorBase<Head, Tail...>
|
|
|
|
: VisitorBase<Head>, RecursiveVisitorBase<Tail...>
|
|
|
|
{
|
|
|
|
using VisitorBase<Head>::visit;
|
|
|
|
using VisitorBase<Head>::post_visit;
|
|
|
|
|
|
|
|
using RecursiveVisitorBase<Tail...>::visit;
|
|
|
|
using RecursiveVisitorBase<Tail...>::post_visit;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename T>
|
2015-10-19 01:44:00 +08:00
|
|
|
struct RecursiveVisitorBase<T> : public VisitorBase<T>
|
2015-08-30 07:12:46 +08:00
|
|
|
{
|
|
|
|
using VisitorBase<T>::visit;
|
|
|
|
using VisitorBase<T>::post_visit;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename... T>
|
2015-10-19 01:44:00 +08:00
|
|
|
struct Visitor : public detail::RecursiveVisitorBase<T...>
|
2015-08-30 07:12:46 +08:00
|
|
|
{
|
|
|
|
using detail::RecursiveVisitorBase<T...>::visit;
|
|
|
|
using detail::RecursiveVisitorBase<T...>::post_visit;
|
|
|
|
};
|