HierarchyGenerators.h

  1 ////////////////////////////////////////////////////////////////////////////////
  2 // The Loki Library
  3 // Copyright (c) 2001 by Andrei Alexandrescu
  4 // This code accompanies the book:
  5 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
  6 //     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
  7 // Permission to use, copy, modify, distribute and sell this software for any 
  8 //     purpose is hereby granted without fee, provided that the above copyright 
  9 //     notice appear in all copies and that both that copyright notice and this 
 10 //     permission notice appear in supporting documentation.
 11 // The author or Addison-Welsey Longman make no representations about the 
 12 //     suitability of this software for any purpose. It is provided "as is" 
 13 //     without express or implied warranty.
 14 ////////////////////////////////////////////////////////////////////////////////
 15 
 16 // Last update: March 05, 2001
 17 
 18 #ifndef HIERARCHYGENERATORS_INC_
 19 #define HIERARCHYGENERATORS_INC_
 20 
 21 #include "Typelist.h"
 22 #include "TypeTraits.h"
 23 #include "EmptyType.h"
 24 
 25 namespace Loki
 26 {
 27 ////////////////////////////////////////////////////////////////////////////////
 28 // class template GenScatterHierarchy
 29 // Generates a scattered hierarchy starting from a typelist and a template
 30 // Invocation (TList is a typelist, Model is a template of one arg):
 31 // GenScatterHierarchy<TList, Model>
 32 // The generated class inherits all classes generated by instantiating the 
 33 // template 'Model' with the types contained in TList 
 34 ////////////////////////////////////////////////////////////////////////////////
 35 
 36     template <class TList, template <class> class Unit>
 37     class GenScatterHierarchy;
 38      
 39     template <class T1, class T2, template <class> class Unit>
 40     class GenScatterHierarchy<Typelist<T1, T2>, Unit>
 41         : public GenScatterHierarchy<T1, Unit>
 42         , public GenScatterHierarchy<T2, Unit>
 43     {
 44     public:
 45         typedef Typelist<T1, T2> TList;
 46         typedef GenScatterHierarchy<T1, Unit> LeftBase;
 47         typedef GenScatterHierarchy<T2, Unit> RightBase;
 48         template <typename T> struct Rebind
 49         {
 50             typedef Unit<T> Result;
 51         };
 52     };
 53      
 54     template <class AtomicType, template <class> class Unit>
 55     class GenScatterHierarchy : public Unit<AtomicType>
 56     {
 57         typedef Unit<AtomicType> LeftBase;
 58         template <typename T> struct Rebind
 59         {
 60             typedef Unit<T> Result;
 61         };
 62     };
 63     
 64     template <template <class> class Unit>
 65     class GenScatterHierarchy<NullType, Unit>
 66     {
 67         template <typename T> struct Rebind
 68         {
 69             typedef Unit<T> Result;
 70         };
 71     };
 72      
 73 ////////////////////////////////////////////////////////////////////////////////
 74 // function template Field
 75 // Accesses a field in an object of a type generated with GenScatterHierarchy
 76 // Invocation (obj is an object of a type H generated with GenScatterHierarchy,
 77 //     T is a type in the typelist used to generate H):
 78 // Field<T>(obj)
 79 // returns a reference to Unit<T>, where Unit is the template used to generate H 
 80 ////////////////////////////////////////////////////////////////////////////////
 81 
 82     template <class T, class H>
 83     typename H::Rebind<T>::Result& Field(H& obj)
 84     {
 85         return obj;
 86     }
 87      
 88     template <class T, class H>
 89     const typename H::Rebind<T>::Result& Field(const H& obj)
 90     {
 91         return obj;
 92     }
 93      
 94 ////////////////////////////////////////////////////////////////////////////////
 95 // function template TupleUnit
 96 // The building block of tuples 
 97 ////////////////////////////////////////////////////////////////////////////////
 98 
 99     template <class T>
100     struct TupleUnit
101     {
102         T value_;
103         operator T&() { return value_; }
104         operator const T&() const { return value_; }
105     };
106 
107 ////////////////////////////////////////////////////////////////////////////////
108 // class template Tuple
109 // Implements a tuple class that holds a number of values and provides field 
110 //     access to them via the Field function (below) 
111 ////////////////////////////////////////////////////////////////////////////////
112 
113     template <class TList>
114     struct Tuple : public GenScatterHierarchy<TList, TupleUnit>
115     {
116     };
117 
118 ////////////////////////////////////////////////////////////////////////////////
119 // helper class template FieldHelper
120 // See Field below
121 ////////////////////////////////////////////////////////////////////////////////
122 
123     template <class H, unsigned int i> struct FieldHelper;
124     
125     template <class H>
126     struct FieldHelper<H, 0>
127     {
128         typedef typename H::TList::Head ElementType;
129         typedef typename H::Rebind<ElementType>::Result UnitType;
130         
131         enum
132         {
133             isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
134             isConst = TypeTraits<H>::isConst
135         };
136 
137         typedef const typename H::LeftBase ConstLeftBase;
138         
139         typedef typename Select<isConst, ConstLeftBase, 
140             typename H::LeftBase>::Result LeftBase;
141             
142         typedef typename Select<isTuple, ElementType, 
143             UnitType>::Result UnqualifiedResultType;
144 
145         typedef typename Select<isConst, const UnqualifiedResultType,
146                         UnqualifiedResultType>::Result ResultType;
147             
148         static ResultType& Do(H& obj)
149         {
150             LeftBase& leftBase = obj;
151             return leftBase;
152         }
153     };
154 
155     template <class H, unsigned int i>
156     struct FieldHelper
157     {
158         typedef typename TL::TypeAt<typename H::TList, i>::Result ElementType;
159         typedef typename H::Rebind<ElementType>::Result UnitType;
160         
161         enum
162         {
163             isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
164             isConst = TypeTraits<H>::isConst
165         };
166 
167         typedef const typename H::RightBase ConstRightBase;
168         
169         typedef typename Select<isConst, ConstRightBase, 
170             typename H::RightBase>::Result RightBase;
171 
172         typedef typename Select<isTuple, ElementType, 
173             UnitType>::Result UnqualifiedResultType;
174 
175         typedef typename Select<isConst, const UnqualifiedResultType,
176                         UnqualifiedResultType>::Result ResultType;
177             
178         static ResultType& Do(H& obj)
179         {
180             RightBase& rightBase = obj;
181             return FieldHelper<RightBase, i - 1>::Do(rightBase);
182         }
183     };
184 
185 ////////////////////////////////////////////////////////////////////////////////
186 // function template Field
187 // Accesses a field in an object of a type generated with GenScatterHierarchy
188 // Invocation (obj is an object of a type H generated with GenScatterHierarchy,
189 //     i is the index of a type in the typelist used to generate H):
190 // Field<i>(obj)
191 // returns a reference to Unit<T>, where Unit is the template used to generate H
192 //     and T is the i-th type in the typelist 
193 ////////////////////////////////////////////////////////////////////////////////
194 
195     template <int i, class H>
196     typename FieldHelper<H, i>::ResultType&
197     Field(H& obj)
198     {
199         return FieldHelper<H, i>::Do(obj);
200     }
201         
202 //    template <int i, class H>
203 //    const typename FieldHelper<H, i>::ResultType&
204 //    Field(const H& obj)
205 //    {
206 //        return FieldHelper<H, i>::Do(obj);
207 //    }
208         
209 ////////////////////////////////////////////////////////////////////////////////
210 // class template GenLinearHierarchy
211 // Generates a linear hierarchy starting from a typelist and a template
212 // Invocation (TList is a typelist, Model is a template of two args):
213 // GenScatterHierarchy<TList, Model>
214 ////////////////////////////////////////////////////////////////////////////////
215 
216     template
217     <
218         class TList,
219         template <class AtomicType, class Base> class Unit,
220         class Root = EmptyType
221     >
222     class GenLinearHierarchy;
223     
224     template
225     <
226         class T1,
227         class T2,
228         template <class, class> class Unit,
229         class Root
230     >
231     class GenLinearHierarchy<Typelist<T1, T2>, Unit, Root>
232         : public Unit< T1, GenLinearHierarchy<T2, Unit, Root> >
233     {
234     };
235 
236     template
237     <
238         class T,
239         template <class, class> class Unit,
240         class Root
241     >
242     class GenLinearHierarchy<Typelist<T, NullType>, Unit, Root>
243         : public Unit<T, Root>
244     {
245     };
246 
247 }   // namespace Loki
248 
249 ////////////////////////////////////////////////////////////////////////////////
250 // Change log:
251 // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
252 ////////////////////////////////////////////////////////////////////////////////
253 
254 #endif // HIERARCHYGENERATORS_INC_
posted @ 2012-10-31 15:15  crazylhf  阅读(185)  评论(0)    收藏  举报