diff options
author | 2006-01-19 02:02:16 +0000 | |
---|---|---|
committer | 2006-01-19 02:02:16 +0000 | |
commit | 523561e7908d2d5bbe05b84ea2c1d9c404728b12 (patch) | |
tree | dd27e67d81e25e314d5fb7d4d98a08b2f9200663 | |
parent | 89413703156dc2b4ec8d83eea4357369503b7f10 (diff) | |
download | paludis-523561e7908d2d5bbe05b84ea2c1d9c404728b12.tar.gz paludis-523561e7908d2d5bbe05b84ea2c1d9c404728b12.tar.xz |
New style const capable visitors
-rw-r--r-- | paludis/all_dep_atom.cc | 1 | ||||
-rw-r--r-- | paludis/all_dep_atom.hh | 5 | ||||
-rw-r--r-- | paludis/any_dep_atom.cc | 1 | ||||
-rw-r--r-- | paludis/any_dep_atom.hh | 8 | ||||
-rw-r--r-- | paludis/block_dep_atom.cc | 1 | ||||
-rw-r--r-- | paludis/block_dep_atom.hh | 6 | ||||
-rw-r--r-- | paludis/dep_atom.hh | 6 | ||||
-rw-r--r-- | paludis/dep_atom_dumper.cc | 37 | ||||
-rw-r--r-- | paludis/dep_atom_dumper.hh | 17 | ||||
-rw-r--r-- | paludis/dep_atom_visitor.cc | 7 | ||||
-rw-r--r-- | paludis/dep_atom_visitor.hh | 34 | ||||
-rw-r--r-- | paludis/dep_list.cc | 12 | ||||
-rw-r--r-- | paludis/dep_list.hh | 9 | ||||
-rw-r--r-- | paludis/files.m4 | 3 | ||||
-rw-r--r-- | paludis/package_dep_atom.cc | 2 | ||||
-rw-r--r-- | paludis/package_dep_atom.hh | 6 | ||||
-rw-r--r-- | paludis/use_dep_atom.cc | 2 | ||||
-rw-r--r-- | paludis/use_dep_atom.hh | 8 | ||||
-rw-r--r-- | paludis/visitor.cc | 4 | ||||
-rw-r--r-- | paludis/visitor.hh | 158 | ||||
-rw-r--r-- | paludis/visitor_TEST.cc | 153 | ||||
-rw-r--r-- | paludis/visitor_pattern-impl.hh | 34 | ||||
-rw-r--r-- | paludis/visitor_pattern.cc | 21 | ||||
-rw-r--r-- | paludis/visitor_pattern.hh | 105 | ||||
-rw-r--r-- | paludis/visitor_pattern_TEST.cc | 192 |
25 files changed, 367 insertions, 465 deletions
diff --git a/paludis/all_dep_atom.cc b/paludis/all_dep_atom.cc index 4db11fe..1e73d78 100644 --- a/paludis/all_dep_atom.cc +++ b/paludis/all_dep_atom.cc @@ -22,7 +22,6 @@ #include "use_dep_atom.hh" #include "package_dep_atom.hh" #include "dep_atom_visitor.hh" -#include "visitor_pattern-impl.hh" using namespace paludis; diff --git a/paludis/all_dep_atom.hh b/paludis/all_dep_atom.hh index 9d499e5..500786c 100644 --- a/paludis/all_dep_atom.hh +++ b/paludis/all_dep_atom.hh @@ -37,8 +37,9 @@ namespace paludis * * \ingroup DepResolver */ - class AllDepAtom : public CompositeDepAtom, - public Visitable<AllDepAtom, DepAtomVisitor> + class AllDepAtom : + public CompositeDepAtom, + public Visitable<AllDepAtom, DepAtomVisitorTypes> { public: /** diff --git a/paludis/any_dep_atom.cc b/paludis/any_dep_atom.cc index e2432b6..730b836 100644 --- a/paludis/any_dep_atom.cc +++ b/paludis/any_dep_atom.cc @@ -22,7 +22,6 @@ #include "use_dep_atom.hh" #include "package_dep_atom.hh" #include "dep_atom_visitor.hh" -#include "visitor_pattern-impl.hh" using namespace paludis; diff --git a/paludis/any_dep_atom.hh b/paludis/any_dep_atom.hh index 002471b..32412c2 100644 --- a/paludis/any_dep_atom.hh +++ b/paludis/any_dep_atom.hh @@ -21,6 +21,7 @@ #define PALUDIS_GUARD_PALUDIS_ANY_DEP_ATOM_HH 1 #include <paludis/composite_dep_atom.hh> +#include <paludis/dep_atom_visitor.hh> /** \file * Declarations for AnyDepAtom. @@ -30,15 +31,14 @@ namespace paludis { - class DepAtomVisitor; - /** * Represents a "|| ( )" dependency block. * * \ingroup DepResolver */ - class AnyDepAtom : public CompositeDepAtom, - public Visitable<AnyDepAtom, DepAtomVisitor> + class AnyDepAtom : + public CompositeDepAtom, + public Visitable<AnyDepAtom, DepAtomVisitorTypes> { public: /** diff --git a/paludis/block_dep_atom.cc b/paludis/block_dep_atom.cc index e0e94b4..b76947b 100644 --- a/paludis/block_dep_atom.cc +++ b/paludis/block_dep_atom.cc @@ -23,7 +23,6 @@ #include "block_dep_atom.hh" #include "package_dep_atom.hh" #include "dep_atom_visitor.hh" -#include "visitor_pattern-impl.hh" using namespace paludis; diff --git a/paludis/block_dep_atom.hh b/paludis/block_dep_atom.hh index 8709bcf..e515f45 100644 --- a/paludis/block_dep_atom.hh +++ b/paludis/block_dep_atom.hh @@ -22,6 +22,7 @@ #include <paludis/dep_atom.hh> #include <paludis/package_dep_atom.hh> +#include <paludis/dep_atom_visitor.hh> /** \file * Declarations for the BlockDepAtom class. @@ -38,8 +39,9 @@ namespace paludis * * \ingroup DepResolver */ - class BlockDepAtom : public DepAtom, - public Visitable<BlockDepAtom, DepAtomVisitor> + class BlockDepAtom : + public DepAtom, + public Visitable<BlockDepAtom, DepAtomVisitorTypes> { private: PackageDepAtom::ConstPointer _atom; diff --git a/paludis/dep_atom.hh b/paludis/dep_atom.hh index 3100851..1029d47 100644 --- a/paludis/dep_atom.hh +++ b/paludis/dep_atom.hh @@ -20,7 +20,8 @@ #ifndef PALUDIS_GUARD_PALUDIS_DEP_ATOM_HH #define PALUDIS_GUARD_PALUDIS_DEP_ATOM_HH 1 -#include <paludis/visitor_pattern.hh> +#include <paludis/visitor.hh> +#include <paludis/dep_atom_visitor.hh> #include <paludis/composite_pattern.hh> #include <paludis/instantiation_policy.hh> #include <paludis/counted_ptr.hh> @@ -33,7 +34,6 @@ namespace paludis { - class DepAtomVisitor; class CompositeDepAtom; /** @@ -42,7 +42,7 @@ namespace paludis * \ingroup DepResolver */ class DepAtom : - public virtual VisitableInterface<DepAtomVisitor>, + public virtual VisitableInterface<DepAtomVisitorTypes>, public virtual Composite<DepAtom, CompositeDepAtom>, private InstantiationPolicy<DepAtom, instantiation_method::NonCopyableTag>, public InternalCounted<DepAtom> diff --git a/paludis/dep_atom_dumper.cc b/paludis/dep_atom_dumper.cc index dd81d82..5eaa96c 100644 --- a/paludis/dep_atom_dumper.cc +++ b/paludis/dep_atom_dumper.cc @@ -25,9 +25,6 @@ #include "dep_atom_visitor.hh" #include "dep_atom_dumper.hh" -#include "visitor_pattern-impl.hh" -#include "composite_visitor_pattern-impl.hh" - using namespace paludis; DepAtomDumper::DepAtomDumper(std::ostream * const o) : @@ -36,39 +33,33 @@ DepAtomDumper::DepAtomDumper(std::ostream * const o) : } void -DepAtomDumper::enter(const AllDepAtom * const) +DepAtomDumper::visit(const AllDepAtom * const a) { *_o << "<all>"; -} - -void -DepAtomDumper::leave(const AllDepAtom * const) -{ + for (CompositeDepAtom::Iterator i(a->begin()), i_end(a->end()) ; + i != i_end ; ++i) + (*i)->accept(this); *_o << "</all>"; } void -DepAtomDumper::enter(const AnyDepAtom * const) +DepAtomDumper::visit(const AnyDepAtom * const a) { *_o << "<any>"; -} - -void -DepAtomDumper::leave(const AnyDepAtom * const) -{ + for (CompositeDepAtom::Iterator i(a->begin()), i_end(a->end()) ; + i != i_end ; ++i) + (*i)->accept(this); *_o << "</any>"; } void -DepAtomDumper::enter(const UseDepAtom * const f) -{ - *_o << "<use flag=\"" << f->flag() << "\" inverse=\"" - << (f->inverse() ? "true" : "false") << "\">"; -} - -void -DepAtomDumper::leave(const UseDepAtom * const) +DepAtomDumper::visit(const UseDepAtom * const a) { + *_o << "<use flag=\"" << a->flag() << "\" inverse=\"" + << (a->inverse() ? "true" : "false") << "\">"; + for (CompositeDepAtom::Iterator i(a->begin()), i_end(a->end()) ; + i != i_end ; ++i) + (*i)->accept(this); *_o << "</use>"; } diff --git a/paludis/dep_atom_dumper.hh b/paludis/dep_atom_dumper.hh index e8f9b3a..fbf20d3 100644 --- a/paludis/dep_atom_dumper.hh +++ b/paludis/dep_atom_dumper.hh @@ -33,11 +33,9 @@ namespace paludis /** * Dump dependency atoms to a stream in pseudo-XML form, for testing. */ - class DepAtomDumper : public DepAtomVisitor, - public VisitsComposite<DepAtomDumper, AllDepAtom>, - public VisitsComposite<DepAtomDumper, AnyDepAtom>, - public VisitsComposite<DepAtomDumper, UseDepAtom>, - private InstantiationPolicy<DepAtomDumper, instantiation_method::NonCopyableTag> + class DepAtomDumper : + public DepAtomVisitorTypes::ConstVisitor, + private InstantiationPolicy<DepAtomDumper, instantiation_method::NonCopyableTag> { private: std::ostream * const _o; @@ -48,14 +46,11 @@ namespace paludis */ DepAtomDumper(std::ostream * const o); - void enter(const AllDepAtom * const); - void leave(const AllDepAtom * const); + void visit(const AllDepAtom * const); - void enter(const AnyDepAtom * const); - void leave(const AnyDepAtom * const); + void visit(const AnyDepAtom * const); - void enter(const UseDepAtom * const); - void leave(const UseDepAtom * const); + void visit(const UseDepAtom * const); void visit(const PackageDepAtom * const); diff --git a/paludis/dep_atom_visitor.cc b/paludis/dep_atom_visitor.cc index 404b795..3ed873f 100644 --- a/paludis/dep_atom_visitor.cc +++ b/paludis/dep_atom_visitor.cc @@ -21,10 +21,3 @@ using namespace paludis; -DepAtomVisitor::DepAtomVisitor() -{ -} - -DepAtomVisitor::~DepAtomVisitor() -{ -} diff --git a/paludis/dep_atom_visitor.hh b/paludis/dep_atom_visitor.hh index d241bab..ff12c45 100644 --- a/paludis/dep_atom_visitor.hh +++ b/paludis/dep_atom_visitor.hh @@ -20,15 +20,7 @@ #ifndef PALUDIS_GUARD_PALUDIS_DEP_ATOM_VISITOR_HH #define PALUDIS_GUARD_PALUDIS_DEP_ATOM_VISITOR_HH 1 -#include <paludis/dep_atom.hh> -#include <paludis/visitor_pattern.hh> -#include <paludis/composite_visitor_pattern.hh> - -/** \file - * Declarations for the DepAtomVisitor base class. - * - * \ingroup DepResolver - */ +#include <paludis/visitor.hh> namespace paludis { @@ -38,28 +30,8 @@ namespace paludis class UseDepAtom; class BlockDepAtom; - /** - * A DepAtomVisitor is a generic base class for traversing a DepAtom - * collection. - */ - class DepAtomVisitor : public virtual Visits<PackageDepAtom>, - public virtual Visits<AllDepAtom>, - public virtual Visits<AnyDepAtom>, - public virtual Visits<UseDepAtom>, - public virtual Visits<BlockDepAtom> - { - protected: - /** - * Constructor. - */ - DepAtomVisitor(); - - public: - /** - * Destructor. - */ - virtual ~DepAtomVisitor(); - }; + typedef VisitorTypes<PackageDepAtom *, AllDepAtom *, AnyDepAtom *, + UseDepAtom *, BlockDepAtom *> DepAtomVisitorTypes; } #endif diff --git a/paludis/dep_list.cc b/paludis/dep_list.cc index c879c18..486ae6f 100644 --- a/paludis/dep_list.cc +++ b/paludis/dep_list.cc @@ -25,8 +25,6 @@ #include "no_resolvable_option_error.hh" #include "circular_dependency_error.hh" #include "internal_error.hh" -#include "visitor_pattern-impl.hh" -#include "composite_visitor_pattern-impl.hh" #include "all_dep_atom.hh" #include "any_dep_atom.hh" #include "block_dep_atom.hh" @@ -145,13 +143,11 @@ DepList::end() const } void -DepList::enter(const AllDepAtom * const) -{ -} - -void -DepList::leave(const AllDepAtom * const) +DepList::visit(const AllDepAtom * const v) { + for (CompositeDepAtom::Iterator i(v->begin()), i_end(v->end()) ; + i != i_end ; ++i) + (*i)->accept(this); } struct DepListEntryMatcher : diff --git a/paludis/dep_list.hh b/paludis/dep_list.hh index 5baaa1e..7bfc6e5 100644 --- a/paludis/dep_list.hh +++ b/paludis/dep_list.hh @@ -58,11 +58,8 @@ namespace paludis class DepList : private InstantiationPolicy<DepList, instantiation_method::NonCopyableTag>, private PrivateImplementationPattern<DepList>, - protected DepAtomVisitor, - protected VisitsComposite<DepList, AllDepAtom> + protected DepAtomVisitorTypes::ConstVisitor { - friend class VisitsComposite<DepList, AllDepAtom>; - private: void _add_in_role(DepAtom::ConstPointer, const std::string & role); @@ -71,9 +68,7 @@ namespace paludis void visit(const UseDepAtom * const); void visit(const AnyDepAtom * const); void visit(const BlockDepAtom * const); - - void enter(const AllDepAtom * const); - void leave(const AllDepAtom * const); + void visit(const AllDepAtom * const); public: /** diff --git a/paludis/files.m4 b/paludis/files.m4 index c62bf8c..361e2a6 100644 --- a/paludis/files.m4 +++ b/paludis/files.m4 @@ -19,7 +19,6 @@ add(`circular_dependency_error', `hh', `cc') add(`comparison_policy', `hh', `cc', `test') add(`composite_dep_atom', `hh', `cc') add(`composite_pattern', `hh', `cc') -add(`composite_visitor_pattern', `hh', `cc', `impl') add(`config_file', `hh', `cc', `test') add(`config_file_error', `hh', `cc') add(`container_entry', `hh', `cc', `test') @@ -116,5 +115,5 @@ add(`version_metadata', `hh', `cc') add(`version_operator', `hh', `cc', `test') add(`version_spec', `hh', `cc', `test') add(`version_spec_collection', `hh', `cc') -add(`visitor_pattern', `hh', `cc', `impl', `test') +add(`visitor', `hh', `cc', `test') diff --git a/paludis/package_dep_atom.cc b/paludis/package_dep_atom.cc index abc2d50..fa4f732 100644 --- a/paludis/package_dep_atom.cc +++ b/paludis/package_dep_atom.cc @@ -26,8 +26,6 @@ #include "package_dep_atom.hh" #include "dep_atom_visitor.hh" -#include "visitor_pattern-impl.hh" - using namespace paludis; PackageDepAtom::PackageDepAtom(const QualifiedPackageName & package) : diff --git a/paludis/package_dep_atom.hh b/paludis/package_dep_atom.hh index 1b3b7a6..8dc4936 100644 --- a/paludis/package_dep_atom.hh +++ b/paludis/package_dep_atom.hh @@ -25,6 +25,7 @@ #include <paludis/version_operator.hh> #include <paludis/slot_name.hh> #include <paludis/version_spec.hh> +#include <paludis/dep_atom_visitor.hh> #include <ostream> /** \file @@ -42,8 +43,9 @@ namespace paludis * * \ingroup DepResolver */ - class PackageDepAtom : public DepAtom, - public Visitable<PackageDepAtom, DepAtomVisitor> + class PackageDepAtom : + public DepAtom, + public Visitable<PackageDepAtom, DepAtomVisitorTypes> { private: QualifiedPackageName _package; diff --git a/paludis/use_dep_atom.cc b/paludis/use_dep_atom.cc index a9de5f4..3448b64 100644 --- a/paludis/use_dep_atom.cc +++ b/paludis/use_dep_atom.cc @@ -23,8 +23,6 @@ #include "package_dep_atom.hh" #include "dep_atom_visitor.hh" -#include "visitor_pattern-impl.hh" - using namespace paludis; UseDepAtom::UseDepAtom(const UseFlagName & flag, bool inverse) : diff --git a/paludis/use_dep_atom.hh b/paludis/use_dep_atom.hh index 37de86e..c1dc54b 100644 --- a/paludis/use_dep_atom.hh +++ b/paludis/use_dep_atom.hh @@ -22,6 +22,7 @@ #include <paludis/composite_dep_atom.hh> #include <paludis/use_flag_name.hh> +#include <paludis/dep_atom_visitor.hh> /** \file * Declarations for the UseDepAtom class. @@ -31,15 +32,14 @@ namespace paludis { - class DepAtomVisitor; - /** * Represents a use? ( ) dependency atom. * * \ingroup DepResolver */ - class UseDepAtom : public CompositeDepAtom, - public Visitable<UseDepAtom, DepAtomVisitor> + class UseDepAtom : + public CompositeDepAtom, + public Visitable<UseDepAtom, DepAtomVisitorTypes> { private: const UseFlagName _flag; diff --git a/paludis/visitor.cc b/paludis/visitor.cc new file mode 100644 index 0000000..ffeab02 --- /dev/null +++ b/paludis/visitor.cc @@ -0,0 +1,4 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +#include "visitor.hh" + diff --git a/paludis/visitor.hh b/paludis/visitor.hh new file mode 100644 index 0000000..639c0e7 --- /dev/null +++ b/paludis/visitor.hh @@ -0,0 +1,158 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2006 Ciaran McCreesh <ciaranm@gentoo.org> + * + * This file is part of the Paludis package manager. Paludis 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 + * 2 of the License, or (at your option) any later version. + * + * Paludis 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 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_VISITOR_HH +#define PALUDIS_GUARD_PALUDIS_VISITOR_HH 1 + +namespace paludis +{ + template <typename NodePtrType_> + class Visits; + + namespace visitor_internals + { + template <unsigned n_> + struct NoType + { + }; + + template <typename> + struct MakePointerToConst; + + template <typename T_> + struct MakePointerToConst<T_ *> + { + typedef const T_ * Type; + }; + } + + template <typename VisitorType_> + class VisitableInterface + { + protected: + virtual ~VisitableInterface() + { + } + + public: + virtual void accept(typename VisitorType_::Visitor * const) = 0; + + virtual void accept(typename VisitorType_::ConstVisitor * const) const = 0; + }; + + template <typename OurType_, typename VisitorType_> + class Visitable : + public virtual VisitableInterface<VisitorType_> + { + protected: + ~Visitable() + { + } + + public: + virtual void accept(typename VisitorType_::Visitor * const v) + { + static_cast<Visits<OurType_ *> *>(v)->visit( + static_cast<OurType_ *>(this)); + } + + virtual void accept(typename VisitorType_::ConstVisitor * const v) const + { + static_cast<Visits<const OurType_ *> *>(v)->visit( + static_cast<const OurType_ *>(this)); + } + }; + + template <typename NodePtrType_> + class Visits + { + protected: + virtual ~Visits() + { + } + + public: + virtual void visit(NodePtrType_ const) = 0; + }; + + template <unsigned n_> + class Visits<const visitor_internals::NoType<n_> * > + { + protected: + virtual ~Visits() + { + } + }; + + template <unsigned n_> + class Visits<visitor_internals::NoType<n_> * > + { + protected: + virtual ~Visits() + { + } + }; + + template < + typename N1_, + typename N2_ = visitor_internals::NoType<2> *, + typename N3_ = visitor_internals::NoType<3> *, + typename N4_ = visitor_internals::NoType<4> *, + typename N5_ = visitor_internals::NoType<5> *, + typename N6_ = visitor_internals::NoType<6> *, + typename N7_ = visitor_internals::NoType<7> *, + typename N8_ = visitor_internals::NoType<8> *, + typename N9_ = visitor_internals::NoType<9> *> + class VisitorTypes + { + private: + VisitorTypes(); + + + public: + class ConstVisitor : + public Visits<typename visitor_internals::MakePointerToConst<N1_>::Type>, + public Visits<typename visitor_internals::MakePointerToConst<N2_>::Type>, + public Visits<typename visitor_internals::MakePointerToConst<N3_>::Type>, + public Visits<typename visitor_internals::MakePointerToConst<N4_>::Type>, + public Visits<typename visitor_internals::MakePointerToConst<N5_>::Type>, + public Visits<typename visitor_internals::MakePointerToConst<N6_>::Type>, + public Visits<typename visitor_internals::MakePointerToConst<N7_>::Type>, + public Visits<typename visitor_internals::MakePointerToConst<N8_>::Type>, + public Visits<typename visitor_internals::MakePointerToConst<N9_>::Type> + { + }; + + class Visitor : + public Visits<N1_>, + public Visits<N2_>, + public Visits<N3_>, + public Visits<N4_>, + public Visits<N5_>, + public Visits<N6_>, + public Visits<N7_>, + public Visits<N8_>, + public Visits<N9_> + { + }; + }; +} + +#endif diff --git a/paludis/visitor_TEST.cc b/paludis/visitor_TEST.cc new file mode 100644 index 0000000..a5dbbce --- /dev/null +++ b/paludis/visitor_TEST.cc @@ -0,0 +1,153 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2006 Ciaran McCreesh <ciaranm@gentoo.org> + * + * This file is part of the Paludis package manager. Paludis 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 + * 2 of the License, or (at your option) any later version. + * + * Paludis 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 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "visitor.hh" +#include "deleter.hh" +#include "indirect_iterator.hh" +#include <test/test_framework.hh> +#include <test/test_runner.hh> +#include <vector> +#include <algorithm> + +using namespace paludis; +using namespace test; + +class Node; +class FooNode; +class BarNode; + +typedef VisitorTypes<FooNode *, BarNode *> NodeVisitorTypes; + +struct Node : + virtual VisitableInterface<NodeVisitorTypes> +{ +}; + +struct FooNode : + Node, + Visitable<FooNode, NodeVisitorTypes> +{ + std::string c_foo() const + { + return "c_foo"; + } + + std::string foo() + { + return "foo"; + } +}; + +struct BarNode : + Node, + Visitable<BarNode, NodeVisitorTypes> +{ + std::string c_bar() const + { + return "c_bar"; + } + + std::string bar() + { + return "bar"; + } +}; + +struct NodeCVisitor : + NodeVisitorTypes::ConstVisitor +{ + std::string r; + + virtual void visit(const FooNode * const f) + { + r.append(f->c_foo()); + } + + virtual void visit(const BarNode * const b) + { + r.append(b->c_bar()); + } +}; + +struct NodeVisitor : + NodeVisitorTypes::Visitor +{ + std::string r; + + virtual void visit(FooNode * const f) + { + r.append(f->foo()); + } + + virtual void visit(BarNode * const b) + { + r.append(b->bar()); + } +}; + +namespace test_cases +{ + struct ConstVisitorTest : TestCase + { + ConstVisitorTest() : TestCase("const visitor") { } + + void run() + { + std::vector<Node *> v; + + v.push_back(new FooNode); + v.push_back(new BarNode); + v.push_back(new FooNode); + + NodeCVisitor c; + TEST_CHECK_EQUAL(c.r, ""); + for (IndirectIterator<std::vector<Node *>::const_iterator, Node> + i(v.begin()), i_end(v.end()) ; i != i_end ; ++i) + i->accept(&c); + TEST_CHECK_EQUAL(c.r, "c_fooc_barc_foo"); + + std::for_each(v.begin(), v.end(), Deleter()); + } + } test_const_visitor; + + struct VisitorTest : TestCase + { + VisitorTest() : TestCase("visitor") { } + + void run() + { + std::vector<Node *> v; + + v.push_back(new FooNode); + v.push_back(new BarNode); + v.push_back(new FooNode); + + NodeVisitor c; + TEST_CHECK_EQUAL(c.r, ""); + for (IndirectIterator<std::vector<Node *>::iterator, Node> + i(v.begin()), i_end(v.end()) ; i != i_end ; ++i) + i->accept(&c); + TEST_CHECK_EQUAL(c.r, "foobarfoo"); + + std::for_each(v.begin(), v.end(), Deleter()); + } + } test_visitor; +} + diff --git a/paludis/visitor_pattern-impl.hh b/paludis/visitor_pattern-impl.hh deleted file mode 100644 index e1f5392..0000000 --- a/paludis/visitor_pattern-impl.hh +++ /dev/null @@ -1,34 +0,0 @@ -/* vim: set sw=4 sts=4 et foldmethod=syntax : */ - -/* - * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@gentoo.org> - * - * This file is part of the Paludis package manager. Paludis is free software; - * you can redistribute it and/or modify it under the terms of the GNU General - * Public License version 2, as published by the Free Software Foundation. - * - * Paludis 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 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef PALUDIS_GUARD_PALUDIS_VISITOR_PATTERN_IMPL_HH -#define PALUDIS_GUARD_PALUDIS_VISITOR_PATTERN_IMPL_HH 1 - -namespace paludis -{ - template <typename VOurType_, typename VVisitorType_> - void - Visitable<VOurType_, VVisitorType_>::accept(VVisitorType_ * const v) const - { - static_cast<Visits<VOurType_> *>(v)->visit( - static_cast<const VOurType_ *>(this)); - } -} - -#endif diff --git a/paludis/visitor_pattern.cc b/paludis/visitor_pattern.cc deleted file mode 100644 index f069ab1..0000000 --- a/paludis/visitor_pattern.cc +++ /dev/null @@ -1,21 +0,0 @@ -/* vim: set sw=4 sts=4 et foldmethod=syntax : */ - -/* - * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@gentoo.org> - * - * This file is part of the Paludis package manager. Paludis is free software; - * you can redistribute it and/or modify it under the terms of the GNU General - * Public License version 2, as published by the Free Software Foundation. - * - * Paludis 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 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "visitor_pattern.hh" - diff --git a/paludis/visitor_pattern.hh b/paludis/visitor_pattern.hh deleted file mode 100644 index c4091ac..0000000 --- a/paludis/visitor_pattern.hh +++ /dev/null @@ -1,105 +0,0 @@ -/* vim: set sw=4 sts=4 et foldmethod=syntax : */ - -/* - * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@gentoo.org> - * - * This file is part of the Paludis package manager. Paludis is free software; - * you can redistribute it and/or modify it under the terms of the GNU General - * Public License version 2, as published by the Free Software Foundation. - * - * Paludis 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 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef PALUDIS_GUARD_PALUDIS_VISITOR_PATTERN_HH -#define PALUDIS_GUARD_PALUDIS_VISITOR_PATTERN_HH 1 - -/** \file - * Declarations for the Visits, Visitable and VisitableInterface - * class templates. You must also include visitor_pattern-impl.hh in - * any implementation files that define subclasses of VisitsComposite - * or Visitable. - * - * \ingroup Utility - */ - -namespace paludis -{ - /** - * Declares that a class can visit a node of type NodeType_. - * - * \ingroup Utility - */ - template <typename NodeType_> - class Visits - { - public: - /** - * Interface: visit a node. - */ - virtual void visit(const NodeType_ * const) = 0; - - /** - * Destructor. - */ - virtual ~Visits() - { - } - }; - - /** - * Declare a class visitable by VIVisitorType_. Used in abstract base - * classes that define a visitable interface but are not themselves - * visitable. Should be inherited virtually. - * - * \ingroup Utility - */ - template <typename VIVisitorType_> - class VisitableInterface - { - public: - /** - * Interface: accept a visitor. - */ - virtual void accept(VIVisitorType_ * const) const = 0; - - /** - * Destructor - */ - virtual ~VisitableInterface() - { - } - }; - - /** - * Declare a class of type VOurType_ visitable by VVisitorType_. Should - * not use virtual inheritance. Can be used in child classes of an - * abstract base class that uses VisitableInterface. - * - * \ingroup Utility - */ - template <typename VOurType_, typename VVisitorType_> - class Visitable : public virtual VisitableInterface<VVisitorType_> - { - public: - /** - * Accept a visitor. - */ - virtual void accept(VVisitorType_ * const v) const; - - /** - * Destructor. - */ - virtual ~Visitable() - { - } - }; -} - -#endif diff --git a/paludis/visitor_pattern_TEST.cc b/paludis/visitor_pattern_TEST.cc deleted file mode 100644 index 7d663d8..0000000 --- a/paludis/visitor_pattern_TEST.cc +++ /dev/null @@ -1,192 +0,0 @@ -/* vim: set sw=4 sts=4 et foldmethod=syntax : */ - -/* - * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@gentoo.org> - * - * This file is part of the Paludis package manager. Paludis is free software; - * you can redistribute it and/or modify it under the terms of the GNU General - * Public License version 2, as published by the Free Software Foundation. - * - * Paludis 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 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "visitor_pattern.hh" -#include "visitor_pattern-impl.hh" -#include "deleter.hh" -#include <test/test_runner.hh> -#include <test/test_framework.hh> -#include <list> -#include <algorithm> -#include <sstream> - -using namespace test; -using namespace paludis; - -/** \file - * Tests for visitor_pattern.hh . - * - * \ingroup Test - */ - -#ifndef DOXYGEN - -class MyVisitorBase; - -class MyBaseClass : public virtual VisitableInterface<MyVisitorBase> -{ - protected: - MyBaseClass() - { - } -}; - -class MyClassOne : public MyBaseClass, - public Visitable<MyClassOne, MyVisitorBase> -{ - public: - MyClassOne() - { - } - - int get_one_thing() const - { - return 1; - } -}; - -class MyClassTwo : public MyBaseClass, - public Visitable<MyClassTwo, MyVisitorBase> -{ - public: - MyClassTwo() - { - } - - std::string get_two_thing() const - { - return "two"; - } -}; - -class MyClassThree : public MyBaseClass, - public Visitable<MyClassThree, MyVisitorBase> -{ - public: - MyClassThree() - { - } -}; - -class MyVisitorBase : public Visits<MyClassOne>, - public Visits<MyClassTwo>, - public Visits<MyClassThree> -{ - protected: - MyVisitorBase() - { - } -}; - -class MyStringifyVisitor : public MyVisitorBase -{ - private: - std::stringstream s; - - public: - MyStringifyVisitor() - { - } - - void visit(const MyClassOne * const one) - { - s << one->get_one_thing(); - } - - void visit(const MyClassTwo * const two) - { - s << two->get_two_thing(); - } - - void visit(const MyClassThree * const) - { - s << "---"; - } - - std::string value() const - { - return s.str(); - } -}; - -class MyCountingVisitor : public MyVisitorBase -{ - private: - int _value; - - public: - MyCountingVisitor() : - _value(0) - { - } - - void visit(const MyClassOne * const) - { - _value += 1; - } - - void visit(const MyClassTwo * const) - { - _value += 2; - } - - void visit(const MyClassThree * const) - { - _value += 3; - } - - int value() const - { - return _value; - } -}; - -#endif - -namespace test_cases -{ - /** - * \test Test visitor pattern. - * - * \ingroup Test - */ - struct VisitorTest : TestCase - { - VisitorTest() : TestCase("visitor") { } - - void run() - { - std::list<MyBaseClass *> items; - items.push_back(new MyClassOne); - items.push_back(new MyClassTwo); - items.push_back(new MyClassThree); - items.push_back(new MyClassOne); - - MyStringifyVisitor v; - std::for_each(items.begin(), items.end(), std::bind2nd(std::mem_fun(&MyBaseClass::accept), &v)); - TEST_CHECK_EQUAL(v.value(), "1two---1"); - - MyCountingVisitor c; - std::for_each(items.begin(), items.end(), std::bind2nd(std::mem_fun(&MyBaseClass::accept), &c)); - TEST_CHECK_EQUAL(c.value(), 1 + 2 + 3 + 1); - - std::for_each(items.begin(), items.end(), Deleter()); - } - } test_visitor; -} |