#ifndef QLOW_VISITOR_H #define QLOW_VISITOR_H namespace qlow { template class Visitor; template class Visitor { public: using ReturnType = R; }; template class Visitor : public Visitor { public: using ReturnType = R; virtual R visit(T& arg, A& arg2) = 0; }; template class Visitor : public Visitor { public: using Visitor::visit; using ReturnType = R; virtual R visit(T& arg, A& arg2) = 0; }; template class Visitable { public: virtual ~Visitable(void) {} virtual RT accept(V& visitor, A& arg2) = 0; }; // // template // class Visitable // { // public: // template // void accept(Visitor& v) // { // v.visit(static_cast(*this)); // } // }; // // //// Visitor template declaration //template //class Visitor; // //// specialization for single type //template //class Visitor { //public: // virtual void visit(T & visitable) = 0; //}; // //// specialization for multiple types //template //class Visitor : public Visitor { //public: // // promote the function(s) from the base class // using Visitor::visit; // // virtual void visit(T & visitable) = 0; //}; // //template //class Visitable { //public: // virtual void accept(Visitor& visitor) = 0; //}; // //template //class VisitableImpl : public virtual Visitable { //public: // virtual void accept(Visitor& visitor) { // visitor.visit(static_cast(*this)); // } //}; // #if 0 template class Visitor; template<> class Visitor<> { public: }; template class Visitor : public Visitor<> { public: virtual void visit(T& arg) = 0; }; template class Visitor : public Visitor { public: using Visitor::visit; virtual void visit(T& arg) = 0; }; // // template // class VisitableBase // { // public: // virtual typename VisitorType::ReturnType accept(VisitorType& visitor); // }; // template class VisitableBase { // public: // using VisitorType = VT; // typename VisitorType::ReturnType accept(VisitorType& visitor) // { // return visitor.visit(static_cast(*this)); // } public: template void accept(T& visitor) { visitor.visit(static_cast(*this)); } }; #endif } #endif // QLOW_VISITOR_H