00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 namespace paludis
00037 {
00038
00039
00040
00041
00042
00043 namespace visitor_cast_internals
00044 {
00045
00046
00047
00048
00049
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
00062
00063
00064
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
00077
00078
00079
00080
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
00101
00102
00103
00104
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
00116
00117
00118
00119
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
00140
00141
00142
00143
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
00166
00167
00168
00169
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
00192
00193
00194
00195
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
00272
00273
00274
00275
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