From ef09730518986bebf8404a173a622b4cc74542ae Mon Sep 17 00:00:00 2001 From: Bassem Girgis Date: Fri, 30 Mar 2018 11:59:39 -0500 Subject: [PATCH] Visitor pattern --- src/behavioral/SConscript | 22 ++++++++++ src/behavioral/visitor/IElement.hpp | 37 ++++++++++++++++ src/behavioral/visitor/IVisitor.hpp | 39 +++++++++++++++++ src/behavioral/visitor/visitor.cpp | 66 +++++++++++++++++++++++++++++ 4 files changed, 164 insertions(+) create mode 100644 src/behavioral/SConscript create mode 100644 src/behavioral/visitor/IElement.hpp create mode 100644 src/behavioral/visitor/IVisitor.hpp create mode 100644 src/behavioral/visitor/visitor.cpp diff --git a/src/behavioral/SConscript b/src/behavioral/SConscript new file mode 100644 index 0000000..14b1f63 --- /dev/null +++ b/src/behavioral/SConscript @@ -0,0 +1,22 @@ +# +# This file is part of cpp-patterns. +# +# cpp-patterns is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# cpp-patterns is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with cpp-patterns. If not, see . +# + +Import('env') + +env.program(targetName='visitorEx', + sources=['visitor/visitor.cpp'], + localSharedLibs=[]) diff --git a/src/behavioral/visitor/IElement.hpp b/src/behavioral/visitor/IElement.hpp new file mode 100644 index 0000000..c26ee17 --- /dev/null +++ b/src/behavioral/visitor/IElement.hpp @@ -0,0 +1,37 @@ +/* + * This file is part of cpp-patterns. + * + * cpp-patterns is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * cpp-patterns is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with cpp-patterns. If not, see . + */ + +#ifndef SRC_BEHAVIORAL_VISITOR_IELEMENT_HPP_ +#define SRC_BEHAVIORAL_VISITOR_IELEMENT_HPP_ + +#include "IVisitor.hpp" + +namespace behavioral { + +namespace visitor { + +struct IElement { + virtual ~IElement() = default; + + virtual void accept(IVisitor& visitor) = 0; +}; + +} // namespace visitor + +} // namespace behavioral + +#endif // SRC_BEHAVIORAL_VISITOR_IELEMENT_HPP_ diff --git a/src/behavioral/visitor/IVisitor.hpp b/src/behavioral/visitor/IVisitor.hpp new file mode 100644 index 0000000..9b6a3b7 --- /dev/null +++ b/src/behavioral/visitor/IVisitor.hpp @@ -0,0 +1,39 @@ +/* + * This file is part of cpp-patterns. + * + * cpp-patterns is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * cpp-patterns is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with cpp-patterns. If not, see . + */ + +#ifndef SRC_BEHAVIORAL_VISITOR_IVISITOR_HPP_ +#define SRC_BEHAVIORAL_VISITOR_IVISITOR_HPP_ + +class ElementA; +class ElementB; + +namespace behavioral { + +namespace visitor { + +struct IVisitor { + virtual ~IVisitor() = default; + + virtual void visit(ElementA& element) = 0; + virtual void visit(ElementB& element) = 0; +}; + +} // namespace visitor + +} // namespace behavioral + +#endif // SRC_BEHAVIORAL_VISITOR_IVISITOR_HPP_ diff --git a/src/behavioral/visitor/visitor.cpp b/src/behavioral/visitor/visitor.cpp new file mode 100644 index 0000000..f0c6f13 --- /dev/null +++ b/src/behavioral/visitor/visitor.cpp @@ -0,0 +1,66 @@ +/* + * This file is part of cpp-patterns. + * + * cpp-patterns is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * cpp-patterns is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with cpp-patterns. If not, see . + */ + +#include "IElement.hpp" +#include "IVisitor.hpp" + +#include +#include +#include +#include + +struct ElementA : public behavioral::visitor::IElement { + virtual void accept(behavioral::visitor::IVisitor& visitor) override + { + std::cout << "ElementA::accept\n"; + visitor.visit(*this); + } +}; + +struct ElementB : public behavioral::visitor::IElement { + virtual void accept(behavioral::visitor::IVisitor& visitor) override + { + std::cout << "ElementB:accept\n"; + visitor.visit(*this); + } +}; + +struct VisitorA : public behavioral::visitor::IVisitor { + virtual void visit(ElementA& element) override + { + std::cout << "VisitorA::visit(ElementA)\n"; + } + + virtual void visit(ElementB& element) override + { + std::cout << "VisitorA::visit(ElementB)\n"; + } +}; + +int +main(int argc, char** argv) +{ + VisitorA va; + + std::vector> a(3); + + a[0].reset(new ElementA()); + a[1].reset(new ElementB()); + a[2].reset(new ElementA()); + + std::for_each(a.begin(), a.end(), [&va](const auto& e) { e->accept(va); }); +}