00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015 #ifndef LOKI_HIERARCHYGENERATORS_INC_
00016 #define LOKI_HIERARCHYGENERATORS_INC_
00017
00018
00019
00020
00021 #include "Typelist.h"
00022 #include "TypeTraits.h"
00023 #include "EmptyType.h"
00024
00025 namespace Loki
00026 {
00027 #if defined(_MSC_VER) && _MSC_VER >= 1300
00028 #pragma warning( push )
00029
00030 #pragma warning( disable : 4584 )
00031 #endif // _MSC_VER
00032
00034
00035
00036
00037
00038
00039
00041
00042 namespace Private
00043 {
00044
00045
00046
00047
00048
00049
00050
00051
00052 template<class, class>
00053 struct ScatterHierarchyTag;
00054 }
00055
00056 template <class TList, template <class> class Unit>
00057 class GenScatterHierarchy;
00058
00059 template <class T1, class T2, template <class> class Unit>
00060 class GenScatterHierarchy<Typelist<T1, T2>, Unit>
00061 : public GenScatterHierarchy<Private::ScatterHierarchyTag<T1, T2>, Unit>
00062 , public GenScatterHierarchy<T2, Unit>
00063 {
00064 public:
00065 typedef Typelist<T1, T2> TList;
00066
00067 typedef GenScatterHierarchy<Private::ScatterHierarchyTag<T1, T2>, Unit> LeftBase;
00068 typedef GenScatterHierarchy<T2, Unit> RightBase;
00069 template <typename T> struct Rebind
00070 {
00071 typedef Unit<T> Result;
00072 };
00073 };
00074
00075
00076 template <class T1, class T2, template <class> class Unit>
00077 class GenScatterHierarchy<Private::ScatterHierarchyTag<T1, T2>, Unit>
00078 : public GenScatterHierarchy<T1, Unit>
00079 {
00080 };
00081
00082 template <class AtomicType, template <class> class Unit>
00083 class GenScatterHierarchy : public Unit<AtomicType>
00084 {
00085 typedef Unit<AtomicType> LeftBase;
00086 template <typename T> struct Rebind
00087 {
00088 typedef Unit<T> Result;
00089 };
00090 };
00091
00092 template <template <class> class Unit>
00093 class GenScatterHierarchy<NullType, Unit>
00094 {
00095 template <typename T> struct Rebind
00096 {
00097 typedef Unit<T> Result;
00098 };
00099 };
00100
00102
00103
00104
00105
00106
00107
00109
00110 template <class T, class H>
00111 typename H::template Rebind<T>::Result& Field(H& obj)
00112 {
00113 return obj;
00114 }
00115
00116 template <class T, class H>
00117 const typename H::template Rebind<T>::Result& Field(const H& obj)
00118 {
00119 return obj;
00120 }
00121
00123
00124
00126
00127 template <class T>
00128 struct TupleUnit
00129 {
00130 T value_;
00131 operator T&() { return value_; }
00132 operator const T&() const { return value_; }
00133 };
00134
00136
00137
00138
00140
00141 template <class TList>
00142 struct Tuple : public GenScatterHierarchy<TList, TupleUnit>
00143 {
00144 };
00145
00147
00148
00150
00151 template <class H, unsigned int i> struct FieldHelper;
00152
00153 template <class H>
00154 struct FieldHelper<H, 0>
00155 {
00156 typedef typename H::TList::Head ElementType;
00157 typedef typename H::template Rebind<ElementType>::Result UnitType;
00158
00159 enum
00160 {
00161 isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
00162 isConst = TypeTraits<H>::isConst
00163 };
00164
00165 typedef const typename H::LeftBase ConstLeftBase;
00166
00167 typedef typename Select<isConst, ConstLeftBase,
00168 typename H::LeftBase>::Result LeftBase;
00169
00170 typedef typename Select<isTuple, ElementType,
00171 UnitType>::Result UnqualifiedResultType;
00172
00173 typedef typename Select<isConst, const UnqualifiedResultType,
00174 UnqualifiedResultType>::Result ResultType;
00175
00176 static ResultType& Do(H& obj)
00177 {
00178 LeftBase& leftBase = obj;
00179 return leftBase;
00180 }
00181 };
00182
00183 template <class H, unsigned int i>
00184 struct FieldHelper
00185 {
00186 typedef typename TL::TypeAt<typename H::TList, i>::Result ElementType;
00187 typedef typename H::template Rebind<ElementType>::Result UnitType;
00188
00189 enum
00190 {
00191 isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
00192 isConst = TypeTraits<H>::isConst
00193 };
00194
00195 typedef const typename H::RightBase ConstRightBase;
00196
00197 typedef typename Select<isConst, ConstRightBase,
00198 typename H::RightBase>::Result RightBase;
00199
00200 typedef typename Select<isTuple, ElementType,
00201 UnitType>::Result UnqualifiedResultType;
00202
00203 typedef typename Select<isConst, const UnqualifiedResultType,
00204 UnqualifiedResultType>::Result ResultType;
00205
00206 static ResultType& Do(H& obj)
00207 {
00208 RightBase& rightBase = obj;
00209 return FieldHelper<RightBase, i - 1>::Do(rightBase);
00210 }
00211 };
00212
00214
00215
00216
00217
00218
00219
00220
00222
00223 template <int i, class H>
00224 typename FieldHelper<H, i>::ResultType&
00225 Field(H& obj)
00226 {
00227 return FieldHelper<H, i>::Do(obj);
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00238
00239
00240
00241
00243
00244 template
00245 <
00246 class TList,
00247 template <class AtomicType, class Base> class Unit,
00248 class Root = EmptyType
00249 >
00250 class GenLinearHierarchy;
00251
00252 template
00253 <
00254 class T1,
00255 class T2,
00256 template <class, class> class Unit,
00257 class Root
00258 >
00259 class GenLinearHierarchy<Typelist<T1, T2>, Unit, Root>
00260 : public Unit< T1, GenLinearHierarchy<T2, Unit, Root> >
00261 {
00262 };
00263
00264 template
00265 <
00266 class T,
00267 template <class, class> class Unit,
00268 class Root
00269 >
00270 class GenLinearHierarchy<Typelist<T, NullType>, Unit, Root>
00271 : public Unit<T, Root>
00272 {
00273 };
00274
00275 template
00276 <
00277 template <class, class> class Unit,
00278 class Root
00279 >
00280 class GenLinearHierarchy<NullType , Unit, Root>
00281 : public Root
00282 {
00283 };
00284
00285 #if defined(_MSC_VER) && _MSC_VER >= 1300
00286 #pragma warning( pop )
00287 #endif
00288 }
00289
00290 #endif // end file guardian
00291