visitor_cast.hh

Go to the documentation of this file.
00001 /* vim: set sw=4 sts=4 et foldmethod=syntax : */
00002 
00003 /*
00004  * Copyright (c) 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_UTIL_VISITOR_CAST_HH
00021 #define PALUDIS_GUARD_PALUDIS_UTIL_VISITOR_CAST_HH 1
00022 
00023 #include <paludis/util/visitor.hh>
00024 #include <tr1/type_traits>
00025 
00026 /** \file
00027  * Declarations for the visitor_cast function.
00028  *
00029  * \ingroup g_visitors
00030  *
00031  * \section Examples
00032  *
00033  * - None at this time.
00034  */
00035 
00036 namespace paludis
00037 {
00038     /**
00039      * For internal use by visitor_cast.
00040      *
00041      * \ingroup g_visitors
00042      */
00043     namespace visitor_cast_internals
00044     {
00045         /**
00046          * Internal use by visitor_cast: fetch the result, or zero.
00047          *
00048          * \ingroup g_visitors
00049          * \since 0.26
00050          */
00051         template <typename T_, bool b_>
00052         struct GetResult
00053         {
00054             static T_ * get(const void * const)
00055             {
00056                 return 0;
00057             }
00058         };
00059 
00060         /**
00061          * Internal use by visitor_cast: fetch the result, or zero.
00062          *
00063          * \ingroup g_visitors
00064          * \since 0.26
00065          */
00066         template <typename T_>
00067         struct GetResult<T_, true>
00068         {
00069             static T_ * get(const T_ * const t)
00070             {
00071                 return t;
00072             }
00073         };
00074 
00075         /**
00076          * Internal use by visitor_cast: implement the visit functions.
00077          *
00078          * \ingroup g_visitors
00079          * \since 0.26
00080          * \nosubgrouping
00081          */
00082         template <typename Result_, typename Heirarchy_, typename Item_>
00083         struct VisitorCastVisitorVisits :
00084             virtual visitor_internals::Visits<const Item_>
00085         {
00086             Result_ * & result;
00087 
00088             VisitorCastVisitorVisits(Result_ * & r) :
00089                 result(r)
00090             {
00091             }
00092 
00093             void visit(const Item_ & i)
00094             {
00095                 result = GetResult<const Result_, std::tr1::is_same<const Result_, const Item_>::value>::get(&i);
00096             }
00097         };
00098 
00099         /**
00100          * Internal use by visitor_cast: implement the visit functions.
00101          *
00102          * \ingroup g_visitors
00103          * \since 0.26
00104          * \nosubgrouping
00105          */
00106         template <typename Result_, typename Heirarchy_, unsigned u_>
00107         struct VisitorCastVisitorVisits<Result_, Heirarchy_, const NoType<u_> >
00108         {
00109             VisitorCastVisitorVisits(Result_ * &)
00110             {
00111             }
00112         };
00113 
00114         /**
00115          * Internal use by visitor_cast: implement the visit functions.
00116          *
00117          * \ingroup g_visitors
00118          * \since 0.26
00119          * \nosubgrouping
00120          */
00121         template <typename Result_, typename Heirarchy_, typename Item_>
00122         struct VisitorCastVisitorVisits<Result_, Heirarchy_, const TreeLeaf<Heirarchy_, Item_> > :
00123             virtual visitor_internals::Visits<const TreeLeaf<Heirarchy_, Item_> >
00124         {
00125             Result_ * & result;
00126 
00127             VisitorCastVisitorVisits(Result_ * & r) :
00128                 result(r)
00129             {
00130             }
00131 
00132             void visit_leaf(const Item_ & i)
00133             {
00134                 result = GetResult<const Result_, std::tr1::is_same<const Result_, const Item_>::value>::get(&i);
00135             }
00136         };
00137 
00138         /**
00139          * Internal use by visitor_cast: implement the visit functions.
00140          *
00141          * \ingroup g_visitors
00142          * \since 0.26
00143          * \nosubgrouping
00144          */
00145         template <typename Result_, typename Heirarchy_, typename Item_>
00146         struct VisitorCastVisitorVisits<Result_, Heirarchy_, const ConstTreeSequence<Heirarchy_, Item_> > :
00147             virtual visitor_internals::Visits<const ConstTreeSequence<Heirarchy_, Item_> >
00148         {
00149             Result_ * & result;
00150 
00151             VisitorCastVisitorVisits(Result_ * & r) :
00152                 result(r)
00153             {
00154             }
00155 
00156             void visit_sequence(const Item_ & i,
00157                     typename Heirarchy_::ConstSequenceIterator,
00158                     typename Heirarchy_::ConstSequenceIterator)
00159             {
00160                 result = GetResult<const Result_, std::tr1::is_same<const Result_, const Item_>::value>::get(&i);
00161             }
00162         };
00163 
00164         /**
00165          * Internal use by visitor_cast: implement the visit functions.
00166          *
00167          * \ingroup g_visitors
00168          * \since 0.26
00169          * \nosubgrouping
00170          */
00171         template <typename Result_, typename Heirarchy_, typename Item_>
00172         struct VisitorCastVisitorVisits<Result_, Heirarchy_, const TreeSequence<Heirarchy_, Item_> > :
00173             virtual visitor_internals::Visits<const TreeSequence<Heirarchy_, Item_> >
00174         {
00175             Result_ * & result;
00176 
00177             VisitorCastVisitorVisits(Result_ * & r) :
00178                 result(r)
00179             {
00180             }
00181 
00182             void visit_sequence(const Item_ & i,
00183                     typename Heirarchy_::SequenceIterator,
00184                     typename Heirarchy_::SequenceIterator)
00185             {
00186                 result = GetResult<const Result_, std::tr1::is_same<const Result_, const Item_>::value>::get(&i);
00187             }
00188         };
00189 
00190         /**
00191          * Internal use by visitor_cast: the visitor used to do the casting.
00192          *
00193          * \ingroup g_visitors
00194          * \since 0.26
00195          * \nosubgrouping
00196          */
00197         template <typename Result_, typename Heirarchy_>
00198         struct VisitorCastVisitor :
00199             ConstVisitor<Heirarchy_>,
00200             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem1>,
00201             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem2>,
00202             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem3>,
00203             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem4>,
00204             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem5>,
00205             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem6>,
00206             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem7>,
00207             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem8>,
00208             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem9>,
00209             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem10>,
00210             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem11>,
00211             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem12>,
00212             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem13>,
00213             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem14>,
00214             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem15>,
00215             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem16>,
00216             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem17>,
00217             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem18>,
00218             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem19>,
00219             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem20>,
00220             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem21>,
00221             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem22>,
00222             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem23>,
00223             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem24>,
00224             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem25>,
00225             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem26>,
00226             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem27>,
00227             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem28>,
00228             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem29>,
00229             VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem30>
00230         {
00231             Result_ * result;
00232 
00233             VisitorCastVisitor() :
00234                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem1>(result),
00235                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem2>(result),
00236                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem3>(result),
00237                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem4>(result),
00238                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem5>(result),
00239                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem6>(result),
00240                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem7>(result),
00241                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem8>(result),
00242                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem9>(result),
00243                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem10>(result),
00244                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem11>(result),
00245                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem12>(result),
00246                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem13>(result),
00247                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem14>(result),
00248                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem15>(result),
00249                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem16>(result),
00250                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem17>(result),
00251                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem18>(result),
00252                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem19>(result),
00253                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem20>(result),
00254                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem21>(result),
00255                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem22>(result),
00256                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem23>(result),
00257                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem24>(result),
00258                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem25>(result),
00259                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem26>(result),
00260                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem27>(result),
00261                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem28>(result),
00262                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem29>(result),
00263                 VisitorCastVisitorVisits<Result_, Heirarchy_, const typename Heirarchy_::ContainedItem30>(result),
00264                 result(0)
00265             {
00266             }
00267         };
00268     }
00269 
00270     /**
00271      * Use a visitor to return either a pointer to the parameter as type Item_,
00272      * or a zero pointer if the item is not of the correct type.
00273      *
00274      * \ingroup g_visitors
00275      * \since 0.26
00276      */
00277     template <typename Result_, typename Item_>
00278     Result_ *
00279     visitor_cast(const Item_ & h)
00280     {
00281         visitor_cast_internals::VisitorCastVisitor<Result_, typename Item_::Heirarchy> v;
00282         h.accept(v);
00283         return v.result;
00284     }
00285 }
00286 
00287 #endif

Generated on Mon Dec 22 19:43:51 2008 for paludis by  doxygen 1.5.7.1