Skip to content

Cooperative Visitor: A Template Technique for Visitor Creation (C++11)

Notifications You must be signed in to change notification settings

tcantenot/Cooperative-Visitor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 

Repository files navigation

Cooperative-Visitor

Flexible and efficient variation of the Visitor design pattern in C++ that accommodates arbitrary argument and return types.

This implementation is based on Anand Shankar Krishnamoorthi's:
Cooperative Visitor: A Template Technique for Visitor Creation

Cooperative Visitor is a template-based technique that allows: <br>

  • Flexibility of acyclic visitor with performance close to cyclic visitor
  • Easier to use, maintain and modify
  • Better semantic names rather than "visit"
  • Easy creation of const/non-const visitors
  • Flexible return and argument types
  • Dynamic configuration of visitation behavior
  • Implementing a default handler
  • Developing template code upon visitor
  • Fallback to nearest ancestor
  • Custom signature for 'visit' methods

This implementation uses C++11 and replaced the "Loki" TypeList by C++11 variadic templates. <br> Only one virtual method is needed for the visitation (dispatching is performed via a custom virtual table (more information in the link above)).
Some efforts have been made to simplify the Visitor utilisation via some macro helpers.

Example:

#include <cassert>

#include <Visitor.hpp>
#include <Visitable.hpp>


class Shape : public Visitable<Shape>
{
    public:
        META_BaseVisitable(Shape)
};

class Circle : public Shape
{
    public:
        META_Visitable(Circle, Shape)
};

class Polygon : public Shape
{
    public:
        META_Visitable(Polygon, Shape)
};

class PolyPolygon : public Polygon
{
    public:
        META_Visitable(PolyPolygon, Polygon)
};

class PolyPolyPolygon : public PolyPolygon
{
    public:
        META_Visitable(PolyPolyPolygon, PolyPolygon)
};


class ShapeVisitor : public Visitor<Shape, bool, float, std::string const &>
{
    public:
        META_Visitor(ShapeVisitor, draw)

        ShapeVisitor()
        {
            META_Visitables(Shape, Circle, Polygon);
        }

    protected:
        bool draw(Shape & shape, float, std::string const &)
        {
            return false;
        }

        bool draw(Circle & circle, float, std::string const &)
        {
            return true;
        }

        bool draw(Polygon & polygon, float, std::string const &)
        {
            return true;
        }
};

int main(int argc, char const ** argv)
{
    Shape shape;
    Circle circle;
    Polygon polygon;
    PolyPolygon pp;
    PolyPolyPolygon ppp;

    ShapeVisitor sv;

    bool b;
    b = sv(shape, 1.0f, "shape");     assert(!b);
    b = sv(circle, 2.0f, "circle");   assert(b);
    b = sv(polygon, 3.0f, "polygon"); assert(b);
    b = sv(pp, 4.0f, "pp");   assert(b); // Fallback to ShapeVisitor::draw(Polygon &, ...)
    b = sv(ppp, 5.0f, "ppp"); assert(b); // Fallback to ShapeVisitor::draw(Polygon &, ...)

    return 0;
}

About

Cooperative Visitor: A Template Technique for Visitor Creation (C++11)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages