visitor.hh

Go to the documentation of this file.
00001 /* vim: set sw=4 sts=4 et foldmethod=syntax : */
00002 
00003 /*
00004  * Copyright (c) 2006, 2007, 2008 Ciaran McCreesh
00005  *
00006  * This file is part of the Paludis package manager. Paludis is free software;
00007  * you can redistribute it and/or modify it under the terms of the GNU General
00008  * Public License version 2, as published by the Free Software Foundation.
00009  *
00010  * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
00011  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00012  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00013  * details.
00014  *
00015  * You should have received a copy of the GNU General Public License along with
00016  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00017  * Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 
00020 #ifndef PALUDIS_GUARD_PALUDIS_VISITOR_HH
00021 #define PALUDIS_GUARD_PALUDIS_VISITOR_HH 1
00022 
00023 #include <paludis/util/attributes.hh>
00024 #include <paludis/util/visitor-fwd.hh>
00025 #include <paludis/util/sequence-fwd.hh>
00026 #include <paludis/util/operators.hh>
00027 #include <paludis/util/wrapped_forward_iterator-fwd.hh>
00028 #include <tr1/memory>
00029 #include <tr1/type_traits>
00030 
00031 /** \file
00032  * Declares the Visitor and related classes.
00033  *
00034  * \ingroup g_visitors
00035  *
00036  * \section Examples
00037  *
00038  * - None at this time.
00039  */
00040 
00041 namespace paludis
00042 {
00043     /**
00044      * \namespace visitor_internals
00045      * \ingroup g_visitors
00046      *
00047      * For internal use by visitor classes.
00048      */
00049     namespace visitor_internals
00050     {
00051         /**
00052          * Derived classes can accept a const visitor of heirarchy H_.
00053          *
00054          * \ingroup g_visitors
00055          * \nosubgrouping
00056          */
00057         template <typename H_>
00058         class PALUDIS_VISIBLE ConstAcceptInterface
00059         {
00060             protected:
00061                 ///\name Visitor operations
00062                 ///\{
00063 
00064                 virtual void real_const_accept(ConstVisitor<H_> &) const = 0;
00065 
00066                 ///\}
00067 
00068             private:
00069                 template <bool b_, typename T_>
00070                 struct PALUDIS_VISIBLE ConstAccept
00071                 {
00072                     static void forward(const ConstAcceptInterface * const h, T_ & t);
00073                 };
00074 
00075                 template <typename T_>
00076                 struct PALUDIS_VISIBLE ConstAccept<false, T_>
00077                 {
00078                     static void forward(const ConstAcceptInterface * const h, T_ & t);
00079                 };
00080 
00081             public:
00082                 ///\name Basic operations
00083                 ///\{
00084 
00085                 virtual ~ConstAcceptInterface();
00086 
00087                 ///\}
00088 
00089                 ///\name Visitor operations
00090                 ///\{
00091 
00092                 typedef H_ Heirarchy;
00093 
00094                 /**
00095                  * Accept a const visitor of either our visitable type, or a
00096                  * visitor that can visit a superset of that heirarchy.
00097                  */
00098                 template <typename V_>
00099                 void const_accept(V_ & v) const
00100                 {
00101                     ConstAccept<std::tr1::is_same<typename H_::Heirarchy, typename V_::Heirarchy>::value, V_>::forward(this, v);
00102                 }
00103 
00104                 /**
00105                  * Accept a const visitor of either our visitable type, or a
00106                  * visitor that can visit a superset of that heirarchy.
00107                  */
00108                 template <typename V_>
00109                 void accept(V_ & v) const
00110                 {
00111                     const_accept(v);
00112                 }
00113 
00114                 ///\}
00115         };
00116 
00117         /**
00118          * Implementation of ConstAcceptInterface for class T_.
00119          *
00120          * \ingroup g_visitors
00121          * \nosubgrouping
00122          */
00123         template <typename H_, typename T_>
00124         class PALUDIS_VISIBLE ConstAcceptInterfaceVisitsThis :
00125             public virtual ConstAcceptInterface<H_>
00126         {
00127             protected:
00128                 ///\name Visitor operations
00129                 ///\{
00130 
00131                 virtual void real_const_accept(ConstVisitor<H_> & v) const;
00132 
00133                 ///\}
00134         };
00135 
00136         /**
00137          * Derived classes can accept a const or non-const visitor of heirarchy H_.
00138          *
00139          * \ingroup g_visitors
00140          * \nosubgrouping
00141          */
00142         template <typename H_>
00143         class PALUDIS_VISIBLE AcceptInterface :
00144             public ConstAcceptInterface<H_>
00145         {
00146             private:
00147                 template <bool b_, typename T_>
00148                 struct PALUDIS_VISIBLE ConstAccept
00149                 {
00150                     static void forward(AcceptInterface * const h, T_ & t);
00151                 };
00152 
00153                 template <typename T_>
00154                 struct PALUDIS_VISIBLE ConstAccept<true, T_>
00155                 {
00156                     static void forward(AcceptInterface * const h, T_ & t);
00157                 };
00158 
00159                 template <bool b_, typename T_>
00160                 struct PALUDIS_VISIBLE Accept
00161                 {
00162                     static void forward(AcceptInterface * const h, T_ & t);
00163                 };
00164 
00165                 template <typename T_>
00166                 struct PALUDIS_VISIBLE Accept<false, T_>
00167                 {
00168                     static void forward(AcceptInterface * const h, T_ & t);
00169                 };
00170 
00171             protected:
00172                 ///\name Visitor operations
00173                 ///\{
00174 
00175                 virtual void real_mutable_accept(Visitor<H_> &) = 0;
00176 
00177                 ///\}
00178 
00179             public:
00180                 ///\name Basic operations
00181                 ///\{
00182 
00183                 virtual ~AcceptInterface();
00184 
00185                 ///\}
00186 
00187                 ///\name Visitor operations
00188                 ///\{
00189 
00190                 template <typename V_>
00191                 void mutable_accept(V_ & v)
00192                 {
00193                     Accept<std::tr1::is_same<typename H_::Heirarchy, typename V_::Heirarchy>::value, V_>::forward(this, v);
00194                 }
00195 
00196                 template <typename V_>
00197                 void accept(V_ & v) const
00198                 {
00199                     const_accept(v);
00200                 }
00201 
00202                 template <typename V_>
00203                 void accept(V_ & v)
00204                 {
00205                     ConstAccept<V_::visitor_is_const, V_>::forward(this, v);
00206                 }
00207 
00208                 ///\}
00209         };
00210 
00211         /**
00212          * Implementation of ConstAcceptInterface for class T_.
00213          *
00214          * \ingroup g_visitors
00215          * \nosubgrouping
00216          */
00217         template <typename H_, typename T_>
00218         class PALUDIS_VISIBLE AcceptInterfaceVisitsThis :
00219             public virtual AcceptInterface<H_>
00220         {
00221             protected:
00222                 ///\name Visitor operations
00223                 ///\{
00224 
00225                 virtual void real_const_accept(ConstVisitor<H_> & v) const;
00226 
00227                 virtual void real_mutable_accept(Visitor<H_> & v);
00228 
00229                 ///\}
00230         };
00231 
00232         /**
00233          * Used to contain a node with no children in a detached visitable
00234          * heirarchy.
00235          *
00236          * \ingroup g_visitors
00237          */
00238         template <typename H_, typename T_>
00239         class PALUDIS_VISIBLE TreeLeaf :
00240             public AcceptInterface<H_>
00241         {
00242             private:
00243                 TreeLeaf(const TreeLeaf &);
00244                 const TreeLeaf & operator= (const TreeLeaf &);
00245 
00246                 const std::tr1::shared_ptr<T_> _item;
00247 
00248             protected:
00249                 ///\name Visitor operations
00250                 ///\{
00251 
00252                 virtual void real_mutable_accept(Visitor<H_> & v);
00253 
00254                 virtual void real_const_accept(ConstVisitor<H_> & v) const;
00255 
00256                 ///\}
00257 
00258             public:
00259                 ///\name Basic operations
00260                 ///\{
00261 
00262                 virtual ~TreeLeaf();
00263 
00264                 TreeLeaf(const std::tr1::shared_ptr<T_> & i);
00265 
00266                 ///\}
00267 
00268                 ///\name Fetch our contained item
00269                 ///\{
00270 
00271                 const std::tr1::shared_ptr<T_> item();
00272 
00273                 const std::tr1::shared_ptr<const T_> item() const;
00274 
00275                 ///\}
00276         };
00277 
00278         /**
00279          * Used to contain a node with a sequence of children in a detached visitable
00280          * heirarchy.
00281          *
00282          * \ingroup g_visitors
00283          */
00284         template <typename H_, typename T_>
00285         class PALUDIS_VISIBLE TreeSequence :
00286             public AcceptInterface<H_>
00287         {
00288             private:
00289                 TreeSequence(const TreeSequence &);
00290                 const TreeSequence & operator= (const TreeSequence &);
00291 
00292                 const std::tr1::shared_ptr<T_> _item;
00293                 const std::tr1::shared_ptr<Sequence<std::tr1::shared_ptr<AcceptInterface<H_> > > > _items;
00294 
00295             protected:
00296                 ///\name Visitor operations
00297                 ///\{
00298 
00299                 virtual void real_mutable_accept(Visitor<H_> & v);
00300 
00301                 virtual void real_const_accept(ConstVisitor<H_> & v) const;
00302 
00303                 ///\}
00304 
00305             public:
00306                 ///\name Basic operations
00307                 ///\{
00308 
00309                 virtual ~TreeSequence();
00310 
00311                 TreeSequence(const std::tr1::shared_ptr<T_> & i);
00312 
00313                 ///\}
00314 
00315                 ///\name Fetch our contained item
00316                 ///\{
00317 
00318                 const std::tr1::shared_ptr<const T_> item() const;
00319 
00320                 const std::tr1::shared_ptr<T_> item();
00321 
00322                 ///\}
00323 
00324                 ///\name Work on our children
00325                 ///\{
00326 
00327                 void add(const std::tr1::shared_ptr<AcceptInterface<H_> > & i);
00328 
00329                 typename H_::ConstSequenceIterator
00330                 const_begin() const;
00331 
00332                 typename H_::ConstSequenceIterator
00333                 const_end() const;
00334 
00335                 typename H_::SequenceIterator
00336                 mutable_begin();
00337 
00338                 typename H_::SequenceIterator
00339                 mutable_end();
00340 
00341                 ///\}
00342         };
00343 
00344         /**
00345          * Used to contain a node with a sequence of children in a detached visitable
00346          * heirarchy, where children can only be created in const form.
00347          *
00348          * \ingroup g_visitors
00349          */
00350         template <typename H_, typename T_>
00351         class PALUDIS_VISIBLE ConstTreeSequence :
00352             public ConstAcceptInterface<H_>
00353         {
00354             private:
00355                 ConstTreeSequence(const ConstTreeSequence &);
00356                 const ConstTreeSequence & operator= (const ConstTreeSequence &);
00357 
00358                 const std::tr1::shared_ptr<T_> _item;
00359                 const std::tr1::shared_ptr<Sequence<std::tr1::shared_ptr<const ConstAcceptInterface<H_> > > > _items;
00360 
00361             protected:
00362                 ///\name Visitor operations
00363                 ///\{
00364 
00365                 virtual void real_const_accept(ConstVisitor<H_> & v) const;
00366 
00367                 ///\}
00368 
00369             public:
00370                 ///\name Basic operations
00371                 ///\{
00372 
00373                 virtual ~ConstTreeSequence();
00374 
00375                 ConstTreeSequence(const std::tr1::shared_ptr<T_> & i);
00376 
00377                 ///\}
00378 
00379                 ///\name Fetch our contained item
00380                 ///\{
00381 
00382                 const std::tr1::shared_ptr<T_> item();
00383 
00384                 const std::tr1::shared_ptr<const T_> item() const;
00385 
00386                 ///\}
00387 
00388                 ///\name Work on our children
00389                 ///\{
00390 
00391                 void add(const std::tr1::shared_ptr<const ConstAcceptInterface<H_> > & i);
00392 
00393                 typename H_::ConstSequenceIterator
00394                 const_begin() const;
00395 
00396                 typename H_::ConstSequenceIterator
00397                 const_end() const;
00398 
00399                 ///\}
00400         };
00401 
00402         /**
00403          * Derived classes can visit an item of type T_.
00404          *
00405          * \ingroup g_visitors
00406          * \nosubgrouping
00407          */
00408         template <typename T_>
00409         class PALUDIS_VISIBLE Visits
00410         {
00411             public:
00412                 ///\name Basic operations
00413                 ///\{
00414 
00415                 virtual ~Visits();
00416 
00417                 ///\}
00418 
00419                 ///\name Visitor operations
00420                 ///\{
00421 
00422                 virtual void visit(T_ &) = 0;
00423 
00424                 ///\}
00425         };
00426 
00427         /**
00428          * Derived classes can visit an item of type T_ (specialisation for
00429          * NoType).
00430          *
00431          * \ingroup g_visitors
00432          * \nosubgrouping
00433          */
00434         template <unsigned u_>
00435         class PALUDIS_VISIBLE Visits<NoType<u_> >
00436         {
00437         };
00438 
00439         /**
00440          * Derived classes can visit an item of type T_ (specialisation for
00441          * NoType).
00442          *
00443          * \ingroup g_visitors
00444          * \nosubgrouping
00445          */
00446         template <unsigned u_>
00447         class PALUDIS_VISIBLE Visits<const NoType<u_> >
00448         {
00449         };
00450 
00451         /**
00452          * Derived classes can visit an item of type T_ (specialisation for
00453          * TreeLeaf).
00454          *
00455          * \ingroup g_visitors
00456          * \nosubgrouping
00457          */
00458         template <typename H_, typename T_>
00459         class PALUDIS_VISIBLE Visits<TreeLeaf<H_, T_> >
00460         {
00461             public:
00462                 ///\name Basic operations
00463                 ///\{
00464 
00465                 virtual ~Visits();
00466 
00467                 ///\}
00468 
00469                 ///\name Visitor operations
00470                 ///\{
00471 
00472                 virtual void visit_leaf(T_ &) = 0;
00473 
00474                 void visit(TreeLeaf<H_, T_> & l);
00475 
00476                 ///\}
00477         };
00478 
00479         /**
00480          * Derived classes can visit an item of type T_ (specialisation for
00481          * TreeLeaf).
00482          *
00483          * \ingroup g_visitors
00484          * \nosubgrouping
00485          */
00486         template <typename H_, typename T_>
00487         class PALUDIS_VISIBLE Visits<const TreeLeaf<H_, T_> >
00488         {
00489             public:
00490                 ///\name Basic operations
00491                 ///\{
00492 
00493                 virtual ~Visits();
00494 
00495                 ///\}
00496 
00497                 ///\name Visitor operations
00498                 ///\{
00499 
00500                 virtual void visit_leaf(const T_ &) = 0;
00501 
00502                 void visit(const TreeLeaf<H_, T_> & l);
00503 
00504                 ///\}
00505         };
00506 
00507         /**
00508          * Derived classes can visit an item of type T_ (specialisation for
00509          * TreeSequence).
00510          *
00511          * \ingroup g_visitors
00512          * \nosubgrouping
00513          */
00514         template <typename H_, typename T_>
00515         class PALUDIS_VISIBLE Visits<TreeSequence<H_, T_> >
00516         {
00517             public:
00518                 ///\name Basic operations
00519                 ///\{
00520 
00521                 virtual ~Visits();
00522 
00523                 ///\}
00524 
00525                 ///\name Visitor operations
00526                 ///\{
00527 
00528                 virtual void visit_sequence(T_ &,
00529                         typename TreeSequenceIteratorTypes<H_>::Iterator,
00530                         typename TreeSequenceIteratorTypes<H_>::Iterator) = 0;
00531 
00532                 void visit(TreeSequence<H_, T_> & s);
00533 
00534                 ///\}
00535         };
00536 
00537         /**
00538          * Derived classes can visit an item of type T_ (specialisation for
00539          * TreeSequence).
00540          *
00541          * \ingroup g_visitors
00542          * \nosubgrouping
00543          */
00544         template <typename H_, typename T_>
00545         class PALUDIS_VISIBLE Visits<const TreeSequence<H_, T_> >
00546         {
00547             public:
00548                 ///\name Basic operations
00549                 ///\{
00550 
00551                 virtual ~Visits();
00552 
00553                 ///\}
00554 
00555                 ///\name Visitor operations
00556                 ///\{
00557 
00558                 virtual void visit_sequence(const T_ &,
00559                         typename TreeSequenceIteratorTypes<H_>::ConstIterator,
00560                         typename TreeSequenceIteratorTypes<H_>::ConstIterator) = 0;
00561 
00562                 void visit(const TreeSequence<H_, T_> & s);
00563 
00564                 ///\}
00565         };
00566 
00567         /**
00568          * Derived classes can visit an item of type T_ (specialisation for
00569          * ConstTreeSequence).
00570          *
00571          * \ingroup g_visitors
00572          * \nosubgrouping
00573          */
00574         template <typename H_, typename T_>
00575         class PALUDIS_VISIBLE Visits<ConstTreeSequence<H_, T_> >
00576         {
00577             public:
00578                 ///\name Basic operations
00579                 ///\{
00580 
00581                 virtual ~Visits();
00582 
00583                 ///\}
00584 
00585                 ///\name Visitor operations
00586                 ///\{
00587 
00588                 virtual void visit_sequence(const T_ &,
00589                         typename TreeSequenceIteratorTypes<H_>::ConstIterator,
00590                         typename TreeSequenceIteratorTypes<H_>::ConstIterator) = 0;
00591 
00592                 void visit(ConstTreeSequence<H_, T_> & s);
00593 
00594                 ///\}
00595         };
00596 
00597         /**
00598          * Derived classes can visit an item of type T_ (specialisation for
00599          * ConstTreeSequence).
00600          *
00601          * \ingroup g_visitors
00602          * \nosubgrouping
00603          */
00604         template <typename H_, typename T_>
00605         class PALUDIS_VISIBLE Visits<const ConstTreeSequence<H_, T_> >
00606         {
00607             public:
00608                 ///\name Basic operations
00609                 ///\{
00610 
00611                 virtual ~Visits();
00612 
00613                 ///\}
00614 
00615                 ///\name Visitor operations
00616                 ///\{
00617 
00618                 virtual void visit_sequence(const T_ &,
00619                         typename TreeSequenceIteratorTypes<H_>::ConstIterator,
00620                         typename TreeSequenceIteratorTypes<H_>::ConstIterator) = 0;
00621 
00622                 void visit(const ConstTreeSequence<H_, T_> & s);
00623 
00624                 ///\}
00625         };
00626 
00627         /**
00628          * Container class providing convenience typedefs for iterators over a
00629          * TreeSequence.
00630          *
00631          * \ingroup g_visitors
00632          * \nosubgrouping
00633          */
00634         template <typename H_>
00635         struct TreeSequenceIteratorTypes
00636         {
00637             ///\name Visitor operations
00638             ///\{
00639 
00640             struct ConstIteratorTag;
00641             typedef WrappedForwardIterator<ConstIteratorTag, const ConstAcceptInterface<H_> > ConstIterator;
00642 
00643             struct IteratorTag;
00644             typedef WrappedForwardIterator<IteratorTag, AcceptInterface<H_> > Iterator;
00645 
00646             ///\}
00647         };
00648 
00649         /**
00650          * Proxy visitor adapter.
00651          *
00652          * \ingroup g_visitors
00653          * \nosubgrouping
00654          */
00655         template <typename H_, typename LargerH_, typename T_>
00656         class PALUDIS_VISIBLE ProxyVisits :
00657             public virtual Visits<T_>
00658         {
00659         };
00660 
00661         /**
00662          * Proxy visitor adapter.
00663          *
00664          * \ingroup g_visitors
00665          * \nosubgrouping
00666          */
00667         template <typename H_, typename LargerH_, unsigned u_>
00668         class PALUDIS_VISIBLE ProxyVisits<H_, LargerH_, NoType<u_> >
00669         {
00670         };
00671 
00672         /**
00673          * Proxy visitor adapter.
00674          *
00675          * \ingroup g_visitors
00676          * \nosubgrouping
00677          */
00678         template <typename H_, typename LargerH_, unsigned u_>
00679         class PALUDIS_VISIBLE ProxyVisits<H_, LargerH_, const NoType<u_> >
00680         {
00681         };
00682 
00683         /**
00684          * Proxy visitor adapter.
00685          *
00686          * \ingroup g_visitors
00687          * \nosubgrouping
00688          */
00689         template <typename H_, typename LargerH_, typename T_>
00690         class PALUDIS_VISIBLE ProxyVisits<H_, LargerH_, const TreeLeaf<H_, T_> > :
00691             public virtual Visits<const TreeLeaf<H_, T_> >
00692         {
00693             public:
00694                 ///\name Basic operations
00695                 ///\{
00696 
00697                 virtual ~ProxyVisits();
00698 
00699                 ///\}
00700 
00701                 ///\name Visitor operations
00702                 ///\{
00703 
00704                 virtual void visit_leaf(const T_ & v);
00705 
00706                 ///\}
00707         };
00708 
00709         /**
00710          * Proxy visitor adapter.
00711          *
00712          * \ingroup g_visitors
00713          * \nosubgrouping
00714          */
00715         template <typename H_, typename LargerH_, typename T_>
00716         class PALUDIS_VISIBLE ProxyVisits<H_, LargerH_, TreeLeaf<H_, T_> > :
00717             public virtual Visits<TreeLeaf<H_, T_> >
00718         {
00719             public:
00720                 ///\name Basic operations
00721                 ///\{
00722 
00723                 virtual ~ProxyVisits();
00724 
00725                 ///\}
00726 
00727                 ///\name Visitor operations
00728                 ///\{
00729 
00730                 virtual void visit_leaf(T_ & v);
00731 
00732                 ///\}
00733         };
00734 
00735         /**
00736          * Proxy visitor adapter.
00737          *
00738          * \ingroup g_visitors
00739          * \nosubgrouping
00740          */
00741         template <typename H_, typename LargerH_, typename T_>
00742         class PALUDIS_VISIBLE ProxyVisits<H_, LargerH_, const ConstTreeSequence<H_, T_> > :
00743             public virtual Visits<const ConstTreeSequence<H_, T_> >
00744         {
00745             public:
00746                 ///\name Basic operations
00747                 ///\{
00748 
00749                 virtual ~ProxyVisits();
00750 
00751                 ///\}
00752 
00753                 ///\name Visitor operations
00754                 ///\{
00755 
00756                 virtual void visit_sequence(const T_ & t,
00757                         typename TreeSequenceIteratorTypes<H_>::ConstIterator c,
00758                         typename TreeSequenceIteratorTypes<H_>::ConstIterator e);
00759 
00760                 ///\}
00761         };
00762 
00763         /**
00764          * Proxy visitor adapter.
00765          *
00766          * \ingroup g_visitors
00767          * \nosubgrouping
00768          */
00769         template <typename H_, typename LargerH_, typename T_>
00770         class PALUDIS_VISIBLE ProxyVisits<H_, LargerH_, const TreeSequence<H_, T_> > :
00771             public virtual Visits<const TreeSequence<H_, T_> >
00772         {
00773             public:
00774                 ///\name Basic operations
00775                 ///\{
00776 
00777                 virtual ~ProxyVisits();
00778 
00779                 ///\}
00780 
00781                 ///\name Visitor operations
00782                 ///\{
00783 
00784                 virtual void visit_sequence(const T_ & t,
00785                         typename TreeSequenceIteratorTypes<H_>::ConstIterator c,
00786                         typename TreeSequenceIteratorTypes<H_>::ConstIterator e);
00787 
00788                 ///\}
00789         };
00790 
00791         /**
00792          * Proxy visitor adapter.
00793          *
00794          * \ingroup g_visitors
00795          * \nosubgrouping
00796          */
00797         template <typename H_, typename LargerH_, typename T_>
00798         class PALUDIS_VISIBLE ProxyVisits<H_, LargerH_, TreeSequence<H_, T_> > :
00799             public virtual Visits<TreeSequence<H_, T_> >
00800         {
00801             public:
00802                 ///\name Basic operations
00803                 ///\{
00804 
00805                 virtual ~ProxyVisits();
00806 
00807                 ///\}
00808 
00809                 ///\name Visitor operations
00810                 ///\{
00811 
00812                 virtual void visit_sequence(T_ & t,
00813                         typename TreeSequenceIteratorTypes<H_>::Iterator c,
00814                         typename TreeSequenceIteratorTypes<H_>::Iterator e);
00815 
00816                 ///\}
00817         };
00818 
00819         /**
00820          * Proxy visitor.
00821          *
00822          * \ingroup g_visitors
00823          * \nosubgrouping
00824          */
00825         template <typename H_, typename LargerH_>
00826         class PALUDIS_VISIBLE ConstProxyVisitor :
00827             public ConstVisitor<H_>,
00828             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem1>,
00829             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem2>,
00830             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem3>,
00831             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem4>,
00832             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem5>,
00833             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem6>,
00834             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem7>,
00835             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem8>,
00836             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem9>,
00837             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem10>,
00838             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem11>,
00839             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem12>,
00840             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem13>,
00841             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem14>,
00842             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem15>,
00843             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem16>,
00844             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem17>,
00845             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem18>,
00846             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem19>,
00847             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem20>,
00848             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem21>,
00849             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem22>,
00850             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem23>,
00851             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem24>,
00852             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem25>,
00853             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem26>,
00854             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem27>,
00855             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem28>,
00856             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem29>,
00857             public ProxyVisits<H_, LargerH_, const typename H_::ContainedItem30>
00858         {
00859             private:
00860                 ConstVisitor<LargerH_> * const _larger_h;
00861 
00862             public:
00863                 ///\name Basic operations
00864                 ///\{
00865 
00866                 ConstProxyVisitor(ConstVisitor<LargerH_> * const l);
00867 
00868                 ///\}
00869 
00870                 ///\name Visitor operations
00871                 ///\{
00872 
00873                 ConstVisitor<LargerH_> * larger_visitor() const;
00874 
00875                 ///\}
00876         };
00877 
00878         /**
00879          * Proxy visitor adapter.
00880          *
00881          * \ingroup g_visitors
00882          * \nosubgrouping
00883          */
00884         template <typename H_, typename LargerH_>
00885         class PALUDIS_VISIBLE ProxyVisitor :
00886             public Visitor<H_>,
00887             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem1>,
00888             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem2>,
00889             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem3>,
00890             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem4>,
00891             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem5>,
00892             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem6>,
00893             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem7>,
00894             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem8>,
00895             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem9>,
00896             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem10>,
00897             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem11>,
00898             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem12>,
00899             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem13>,
00900             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem14>,
00901             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem15>,
00902             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem16>,
00903             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem17>,
00904             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem18>,
00905             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem19>,
00906             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem20>,
00907             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem21>,
00908             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem22>,
00909             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem23>,
00910             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem24>,
00911             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem25>,
00912             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem26>,
00913             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem27>,
00914             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem28>,
00915             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem29>,
00916             public ProxyVisits<H_, LargerH_, typename H_::ContainedItem30>
00917         {
00918             private:
00919                 Visitor<LargerH_> * const _larger_h;
00920 
00921             public:
00922                 ///\name Basic operations
00923                 ///\{
00924 
00925                 ProxyVisitor(Visitor<LargerH_> * const l);
00926 
00927                 ///\}
00928 
00929                 ///\name Visitor operations
00930                 ///\{
00931 
00932                 Visitor<LargerH_> * larger_visitor() const;
00933 
00934                 ///\}
00935         };
00936 
00937         /**
00938          * Proxy visitor adapter iterator.
00939          *
00940          * \ingroup g_visitors
00941          * \nosubgrouping
00942          */
00943         template <typename H_, typename LargerH_>
00944         class PALUDIS_VISIBLE ConstProxyIterator :
00945             public paludis::equality_operators::HasEqualityOperators
00946         {
00947             private:
00948                 struct PALUDIS_VISIBLE Adapter :
00949                     ConstAcceptInterface<LargerH_>
00950                 {
00951                     const ConstAcceptInterface<H_> & _i;
00952 
00953                     Adapter(const ConstAcceptInterface<H_> & i);
00954 
00955                     void real_const_accept(ConstVisitor<LargerH_> & v) const;
00956                 };
00957 
00958                 typename TreeSequenceIteratorTypes<H_>::ConstIterator _i;
00959                 mutable std::tr1::shared_ptr<Adapter> _c;
00960 
00961             public:
00962                 ///\name Basic operations
00963                 ///\{
00964 
00965                 ConstProxyIterator(typename TreeSequenceIteratorTypes<H_>::ConstIterator i);
00966 
00967                 bool operator== (const ConstProxyIterator & other) const;
00968 
00969                 const ConstAcceptInterface<LargerH_> * operator-> () const;
00970 
00971                 const ConstAcceptInterface<LargerH_> & operator* () const;
00972 
00973                 ConstProxyIterator & operator++ ();
00974 
00975                 ///\}
00976         };
00977 
00978         /**
00979          * Proxy visitor adapter iterator.
00980          *
00981          * \ingroup g_visitors
00982          * \nosubgrouping
00983          */
00984         template <typename H_, typename LargerH_>
00985         class PALUDIS_VISIBLE ProxyIterator :
00986             public paludis::equality_operators::HasEqualityOperators
00987         {
00988             private:
00989                 struct PALUDIS_VISIBLE Adapter :
00990                     AcceptInterface<LargerH_>
00991                 {
00992                     AcceptInterface<H_> & _i;
00993 
00994                     Adapter(AcceptInterface<H_> & i);
00995 
00996                     void real_const_accept(ConstVisitor<LargerH_> & v) const;
00997 
00998                     void real_mutable_accept(Visitor<LargerH_> & v);
00999                 };
01000 
01001                 typename TreeSequenceIteratorTypes<H_>::Iterator _i;
01002                 mutable std::tr1::shared_ptr<Adapter> _c;
01003 
01004             public:
01005                 ///\name Basic operations
01006                 ///\{
01007 
01008                 ProxyIterator(typename TreeSequenceIteratorTypes<H_>::Iterator i);
01009 
01010                 bool operator== (const ProxyIterator & other) const;
01011 
01012                 AcceptInterface<LargerH_> * operator-> () const;
01013 
01014                 AcceptInterface<LargerH_> & operator* () const;
01015 
01016                 ProxyIterator & operator++ ();
01017 
01018                 ///\}
01019         };
01020 
01021         /**
01022          * Define policy for a set of visitor types.
01023          *
01024          * \ingroup g_visitors
01025          * \nosubgrouping
01026          */
01027         template <
01028             typename Heirarchy_,
01029             typename BasicNode_,
01030             typename ContainedItem1_,
01031             typename ContainedItem2_,
01032             typename ContainedItem3_,
01033             typename ContainedItem4_,
01034             typename ContainedItem5_,
01035             typename ContainedItem6_,
01036             typename ContainedItem7_,
01037             typename ContainedItem8_,
01038             typename ContainedItem9_,
01039             typename ContainedItem10_,
01040             typename ContainedItem11_,
01041             typename ContainedItem12_,
01042             typename ContainedItem13_,
01043             typename ContainedItem14_,
01044             typename ContainedItem15_,
01045             typename ContainedItem16_,
01046             typename ContainedItem17_,
01047             typename ContainedItem18_,
01048             typename ContainedItem19_,
01049             typename ContainedItem20_,
01050             typename ContainedItem21_,
01051             typename ContainedItem22_,
01052             typename ContainedItem23_,
01053             typename ContainedItem24_,
01054             typename ContainedItem25_,
01055             typename ContainedItem26_,
01056             typename ContainedItem27_,
01057             typename ContainedItem28_,
01058             typename ContainedItem29_,
01059             typename ContainedItem30_>
01060         class VisitorTypes
01061         {
01062             public:
01063                 ///\name Visitor type definitions
01064                 ///\{
01065 
01066                 typedef Heirarchy_ Heirarchy;
01067                 typedef BasicNode_ BasicNode;
01068 
01069                 typedef ContainedItem1_ ContainedItem1;
01070                 typedef ContainedItem2_ ContainedItem2;
01071                 typedef ContainedItem3_ ContainedItem3;
01072                 typedef ContainedItem4_ ContainedItem4;
01073                 typedef ContainedItem5_ ContainedItem5;
01074                 typedef ContainedItem6_ ContainedItem6;
01075                 typedef ContainedItem7_ ContainedItem7;
01076                 typedef ContainedItem8_ ContainedItem8;
01077                 typedef ContainedItem9_ ContainedItem9;
01078                 typedef ContainedItem10_ ContainedItem10;
01079                 typedef ContainedItem11_ ContainedItem11;
01080                 typedef ContainedItem12_ ContainedItem12;
01081                 typedef ContainedItem13_ ContainedItem13;
01082                 typedef ContainedItem14_ ContainedItem14;
01083                 typedef ContainedItem15_ ContainedItem15;
01084                 typedef ContainedItem16_ ContainedItem16;
01085                 typedef ContainedItem17_ ContainedItem17;
01086                 typedef ContainedItem18_ ContainedItem18;
01087                 typedef ContainedItem19_ ContainedItem19;
01088                 typedef ContainedItem20_ ContainedItem20;
01089                 typedef ContainedItem21_ ContainedItem21;
01090                 typedef ContainedItem22_ ContainedItem22;
01091                 typedef ContainedItem23_ ContainedItem23;
01092                 typedef ContainedItem24_ ContainedItem24;
01093                 typedef ContainedItem25_ ContainedItem25;
01094                 typedef ContainedItem26_ ContainedItem26;
01095                 typedef ContainedItem27_ ContainedItem27;
01096                 typedef ContainedItem28_ ContainedItem28;
01097                 typedef ContainedItem29_ ContainedItem29;
01098                 typedef ContainedItem30_ ContainedItem30;
01099 
01100                 typedef AcceptInterface<Heirarchy_> Item;
01101                 typedef const ConstAcceptInterface<Heirarchy_> ConstItem;
01102 
01103                 typedef typename TreeSequenceIteratorTypes<Heirarchy_>::Iterator SequenceIterator;
01104                 typedef typename TreeSequenceIteratorTypes<Heirarchy_>::ConstIterator ConstSequenceIterator;
01105 
01106                 ///\}
01107         };
01108 
01109         /**
01110          * A ConstVisitor visits a visitable heirarchy.
01111          *
01112          * \nosubgrouping
01113          * \ingroup g_visitors
01114          */
01115         template <typename H_>
01116         class PALUDIS_VISIBLE ConstVisitor :
01117             public virtual Visits<const typename H_::ContainedItem1>,
011