Last active
April 26, 2016 10:04
-
-
Save mirth/0ff4ca8f414019d1eeffde0eec881f52 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <memory> | |
#include <vector> | |
#include "visitor.hpp" | |
struct foo; | |
struct bar; | |
using visitor_t = basic_visitor<std::tuple<foo, bar>, void(int)>; | |
struct foo: public basic_visitable<foo, visitor_t> { | |
}; | |
struct bar: public basic_visitable<bar, visitor_t> { | |
}; | |
class concrete_visitor0: public visitor_t { | |
public: | |
void visit(foo&, int i) override { | |
std::cout << "concrete_visitor0 visiting foo " << i << '\n'; | |
} | |
void visit(bar&, int i) override { | |
std::cout << "concrete_visitor0 visiting bar " << i << '\n'; | |
} | |
}; | |
class concrete_visitor1: public visitor_t { | |
public: | |
void visit(foo&, int i) override { | |
std::cout << "concrete_visitor1 visiting foo " << i << '\n'; | |
} | |
void visit(bar&, int i) override { | |
std::cout << "concrete_visitor1 visiting bar " << i << '\n'; | |
} | |
}; | |
int main() { | |
{ | |
concrete_visitor0 visitor0; | |
concrete_visitor1 visitor1; | |
foo target; | |
target.accept(visitor0, 1); | |
target.accept(visitor1, 1); | |
} | |
{ | |
std::vector<std::unique_ptr<basic_visitable_pure<visitor_t>>> vec; | |
vec.emplace_back(std::make_unique<foo>()); | |
vec.emplace_back(std::make_unique<bar>()); | |
concrete_visitor0 visitor; | |
for(auto& obj : vec) { | |
obj->accept(visitor, 2); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <tuple> | |
template<typename TargetsVector, typename SignatureVector> | |
struct visit_method; | |
template<typename TargetType, typename ReturnType, typename ... ArgsTypes> | |
struct visit_method<TargetType, ReturnType(ArgsTypes ...)> { | |
virtual ReturnType visit(TargetType&, ArgsTypes...) = 0; | |
virtual ~visit_method() { | |
} | |
}; | |
template<typename TargetsVector, typename SignatureVector> | |
struct basic_visitor; | |
template<typename ... TargetsTypes, typename ReturnType, typename ... ArgsTypes> | |
struct basic_visitor<std::tuple<TargetsTypes ...>, ReturnType(ArgsTypes ...)> : visit_method<TargetsTypes, ReturnType(ArgsTypes ...)> ... | |
{ | |
template<typename VisitableType> | |
ReturnType visit_name_lookup_adhoc(VisitableType& visitable, ArgsTypes... args) { | |
using VisitMethod = visit_method<VisitableType, ReturnType(ArgsTypes ...)>; | |
auto const hack = &VisitMethod::visit; | |
return (this->*hack)(visitable, args...); | |
} | |
}; | |
template<typename VisitorType> | |
struct basic_visitable_pure; | |
template<typename TargetsVector, typename ReturnType, typename ... ArgsTypes> | |
struct basic_visitable_pure<basic_visitor<TargetsVector, ReturnType(ArgsTypes ...)>> | |
{ | |
using visitor_type = basic_visitor<TargetsVector, ReturnType(ArgsTypes ...)>; | |
virtual ReturnType accept(visitor_type& visitor, ArgsTypes... args) = 0; | |
virtual ~basic_visitable_pure() { | |
} | |
}; | |
template<typename SelfType, typename VisitorType> | |
struct basic_visitable; | |
template<typename SelfType, typename TargetsVector, typename ReturnType, typename ... ArgsTypes> | |
struct basic_visitable<SelfType, basic_visitor<TargetsVector, ReturnType(ArgsTypes ...)>>: basic_visitable_pure<basic_visitor<TargetsVector, ReturnType(ArgsTypes ...)>> | |
{ | |
using basic_type = basic_visitable_pure<basic_visitor<TargetsVector, ReturnType(ArgsTypes ...)>>; | |
ReturnType accept(typename basic_type::visitor_type& visitor, ArgsTypes ... args) { | |
return visitor.visit_name_lookup_adhoc(static_cast<SelfType&>(*this), args ...); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment