Skip to content

Instantly share code, notes, and snippets.

@christianparpart
Created November 5, 2018 16:33
Show Gist options
  • Select an option

  • Save christianparpart/095de910dc925100c4ae52cbaf034b71 to your computer and use it in GitHub Desktop.

Select an option

Save christianparpart/095de910dc925100c4ae52cbaf034b71 to your computer and use it in GitHub Desktop.
some super-generic visitor API
// This file is part of the "klex" project, http://github.com/christianparpart/klex>
// (c) 2018 Christian Parpart <christian@parpart.family>
//
// Licensed under the MIT License (the "License"); you may not use this
// file except in compliance with the License. You may obtain a copy of
// the License at: http://opensource.org/licenses/MIT
#pragma once
#include <type_traits>
namespace klex::util {
namespace detail {
template <const bool B, typename T = void> struct add_const_if {};
template <typename T> struct add_const_if<true, T> {
using type = typename std::add_const<T>::type;
};
template <const bool Mutable, typename T>
class Visit {
public:
using Type = typename add_const_if<!Mutable, T>::type;
virtual ~Visit() = default;
virtual void visit(Type&) {}
virtual void endVisit(Type&) {}
};
}
template <const bool Mutable, typename... T>
class Visitor : public detail::Visit<Mutable, T>... {
public:
virtual ~Visitor() = default;
using detail::Visit<Mutable, T>::visit...;
using detail::Visit<Mutable, T>::endVisit...;
};
// Example:
// using ASTVisitor = util::Visitor<false, OptionalExpr, ClosureExpr, NonTerminalExpr, Terminal, Grammar>;
// using ASTRewriter = util::Visitor<true, OptionalExpr, ClosureExpr, NonTerminalExpr, Terminal, Grammar>;
} // namespace klex::util
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment