~ubuntu-branches/ubuntu/wily/tora/wily-proposed

« back to all changes in this revision

Viewing changes to ext/loki/loki-0.1.4/include/loki/HierarchyGenerators.h

  • Committer: Bazaar Package Importer
  • Author(s): Albin Tonnerre
  • Date: 2007-05-29 13:13:36 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070529131336-85ygaddivvmkd3xc
Tags: 1.3.21pre22-1ubuntu1
* Merge from Debian unstable. Remaining Ubuntu changes:
  - debian/rules: call dh_iconcache
  - Remove g++ build dependency
* Modify Maintainer value to match Debian-Maintainer-Field Spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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-Wesley 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
#ifndef LOKI_HIERARCHYGENERATORS_INC_
 
17
#define LOKI_HIERARCHYGENERATORS_INC_
 
18
 
 
19
// $Header: /cvsroot/loki-lib/loki/include/loki/HierarchyGenerators.h,v 1.5 2006/01/16 19:05:09 rich_sposato Exp $
 
20
 
 
21
#include "Typelist.h"
 
22
#include "TypeTraits.h"
 
23
#include "EmptyType.h"
 
24
 
 
25
namespace Loki
 
26
{
 
27
#if defined(_MSC_VER) && _MSC_VER >= 1300
 
28
#pragma warning( push ) 
 
29
 // 'class1' : base-class 'class2' is already a base-class of 'class3'
 
30
#pragma warning( disable : 4584 )
 
31
#endif // _MSC_VER
 
32
 
 
33
////////////////////////////////////////////////////////////////////////////////
 
34
// class template GenScatterHierarchy
 
35
// Generates a scattered hierarchy starting from a typelist and a template
 
36
// Invocation (TList is a typelist, Unit is a template of one arg):
 
37
// GenScatterHierarchy<TList, Unit>
 
38
// The generated class inherits all classes generated by instantiating the 
 
39
// template 'Unit' with the types contained in TList 
 
40
////////////////////////////////////////////////////////////////////////////////
 
41
 
 
42
    namespace Private
 
43
    {
 
44
        // The following type helps to overcome subtle flaw in the original 
 
45
        // implementation of GenScatterHierarchy. 
 
46
        // The flaw is revealed when the input type list of GenScatterHierarchy 
 
47
        // contains more then one element of the same type (e.g. LOKI_TYPELIST_2(int, int)). 
 
48
        // In this case GenScatterHierarchy will contain multiple bases of the same 
 
49
        // type and some of them will not be reachable (per 10.3).
 
50
        // For example before the fix the first element of Tuple<LOKI_TYPELIST_2(int, int)>
 
51
        // is not reachable in any way!
 
52
        template<class, class> 
 
53
        struct ScatterHierarchyTag;
 
54
    }
 
55
 
 
56
    template <class TList, template <class> class Unit>
 
57
    class GenScatterHierarchy;
 
58
     
 
59
    template <class T1, class T2, template <class> class Unit>
 
60
    class GenScatterHierarchy<Typelist<T1, T2>, Unit>
 
61
        : public GenScatterHierarchy<Private::ScatterHierarchyTag<T1, T2>, Unit>
 
62
        , public GenScatterHierarchy<T2, Unit>
 
63
    {
 
64
    public:
 
65
        typedef Typelist<T1, T2> TList;
 
66
        // Insure that LeftBase is unique and therefore reachable
 
67
        typedef GenScatterHierarchy<Private::ScatterHierarchyTag<T1, T2>, Unit> LeftBase;
 
68
        typedef GenScatterHierarchy<T2, Unit> RightBase;
 
69
        template <typename T> struct Rebind
 
70
        {
 
71
            typedef Unit<T> Result;
 
72
        };
 
73
    };
 
74
     
 
75
    // In the middle *unique* class that resolve possible ambiguity
 
76
    template <class T1, class T2, template <class> class Unit>
 
77
    class GenScatterHierarchy<Private::ScatterHierarchyTag<T1, T2>, Unit> 
 
78
        : public GenScatterHierarchy<T1, Unit>
 
79
    {
 
80
    };
 
81
 
 
82
    template <class AtomicType, template <class> class Unit>
 
83
    class GenScatterHierarchy : public Unit<AtomicType>
 
84
    {
 
85
        typedef Unit<AtomicType> LeftBase;
 
86
        template <typename T> struct Rebind
 
87
        {
 
88
            typedef Unit<T> Result;
 
89
        };
 
90
    };
 
91
    
 
92
    template <template <class> class Unit>
 
93
    class GenScatterHierarchy<NullType, Unit>
 
94
    {
 
95
        template <typename T> struct Rebind
 
96
        {
 
97
            typedef Unit<T> Result;
 
98
        };
 
99
    };
 
100
     
 
101
////////////////////////////////////////////////////////////////////////////////
 
102
// function template Field
 
103
// Accesses a field in an object of a type generated with GenScatterHierarchy
 
104
// Invocation (obj is an object of a type H generated with GenScatterHierarchy,
 
105
//     T is a type in the typelist used to generate H):
 
106
// Field<T>(obj)
 
107
// returns a reference to Unit<T>, where Unit is the template used to generate H 
 
108
////////////////////////////////////////////////////////////////////////////////
 
109
 
 
110
    template <class T, class H>
 
111
    typename H::template Rebind<T>::Result& Field(H& obj)
 
112
    {
 
113
        return obj;
 
114
    }
 
115
     
 
116
    template <class T, class H>
 
117
    const typename H::template Rebind<T>::Result& Field(const H& obj)
 
118
    {
 
119
        return obj;
 
120
    }
 
121
     
 
122
////////////////////////////////////////////////////////////////////////////////
 
123
// function template TupleUnit
 
124
// The building block of tuples 
 
125
////////////////////////////////////////////////////////////////////////////////
 
126
 
 
127
    template <class T>
 
128
    struct TupleUnit
 
129
    {
 
130
        T value_;
 
131
        operator T&() { return value_; }
 
132
        operator const T&() const { return value_; }
 
133
    };
 
134
 
 
135
////////////////////////////////////////////////////////////////////////////////
 
136
// class template Tuple
 
137
// Implements a tuple class that holds a number of values and provides field 
 
138
//     access to them via the Field function (below) 
 
139
////////////////////////////////////////////////////////////////////////////////
 
140
 
 
141
    template <class TList>
 
142
    struct Tuple : public GenScatterHierarchy<TList, TupleUnit>
 
143
    {
 
144
    };
 
145
 
 
146
////////////////////////////////////////////////////////////////////////////////
 
147
// helper class template FieldHelper
 
148
// See Field below
 
149
////////////////////////////////////////////////////////////////////////////////
 
150
 
 
151
    template <class H, unsigned int i> struct FieldHelper;
 
152
    
 
153
    template <class H>
 
154
    struct FieldHelper<H, 0>
 
155
    {
 
156
        typedef typename H::TList::Head ElementType;
 
157
        typedef typename H::template Rebind<ElementType>::Result UnitType;
 
158
        
 
159
        enum
 
160
        {
 
161
            isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
 
162
            isConst = TypeTraits<H>::isConst
 
163
        };
 
164
 
 
165
        typedef const typename H::LeftBase ConstLeftBase;
 
166
        
 
167
        typedef typename Select<isConst, ConstLeftBase, 
 
168
            typename H::LeftBase>::Result LeftBase;
 
169
            
 
170
        typedef typename Select<isTuple, ElementType, 
 
171
            UnitType>::Result UnqualifiedResultType;
 
172
 
 
173
        typedef typename Select<isConst, const UnqualifiedResultType,
 
174
                        UnqualifiedResultType>::Result ResultType;
 
175
            
 
176
        static ResultType& Do(H& obj)
 
177
        {
 
178
            LeftBase& leftBase = obj;
 
179
            return leftBase;
 
180
        }
 
181
    };
 
182
 
 
183
    template <class H, unsigned int i>
 
184
    struct FieldHelper
 
185
    {
 
186
        typedef typename TL::TypeAt<typename H::TList, i>::Result ElementType;
 
187
        typedef typename H::template Rebind<ElementType>::Result UnitType;
 
188
        
 
189
        enum
 
190
        {
 
191
            isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
 
192
            isConst = TypeTraits<H>::isConst
 
193
        };
 
194
 
 
195
        typedef const typename H::RightBase ConstRightBase;
 
196
        
 
197
        typedef typename Select<isConst, ConstRightBase, 
 
198
            typename H::RightBase>::Result RightBase;
 
199
 
 
200
        typedef typename Select<isTuple, ElementType, 
 
201
            UnitType>::Result UnqualifiedResultType;
 
202
 
 
203
        typedef typename Select<isConst, const UnqualifiedResultType,
 
204
                        UnqualifiedResultType>::Result ResultType;
 
205
            
 
206
        static ResultType& Do(H& obj)
 
207
        {
 
208
            RightBase& rightBase = obj;
 
209
            return FieldHelper<RightBase, i - 1>::Do(rightBase);
 
210
        }
 
211
    };
 
212
 
 
213
////////////////////////////////////////////////////////////////////////////////
 
214
// function template Field
 
215
// Accesses a field in an object of a type generated with GenScatterHierarchy
 
216
// Invocation (obj is an object of a type H generated with GenScatterHierarchy,
 
217
//     i is the index of a type in the typelist used to generate H):
 
218
// Field<i>(obj)
 
219
// returns a reference to Unit<T>, where Unit is the template used to generate H
 
220
//     and T is the i-th type in the typelist 
 
221
////////////////////////////////////////////////////////////////////////////////
 
222
 
 
223
    template <int i, class H>
 
224
    typename FieldHelper<H, i>::ResultType&
 
225
    Field(H& obj)
 
226
    {
 
227
        return FieldHelper<H, i>::Do(obj);
 
228
    }
 
229
        
 
230
//    template <int i, class H>
 
231
//    const typename FieldHelper<H, i>::ResultType&
 
232
//    Field(const H& obj)
 
233
//    {
 
234
//        return FieldHelper<H, i>::Do(obj);
 
235
//    }
 
236
        
 
237
////////////////////////////////////////////////////////////////////////////////
 
238
// class template GenLinearHierarchy
 
239
// Generates a linear hierarchy starting from a typelist and a template
 
240
// Invocation (TList is a typelist, Unit is a template of two args):
 
241
// GenScatterHierarchy<TList, Unit>
 
242
////////////////////////////////////////////////////////////////////////////////
 
243
 
 
244
    template
 
245
    <
 
246
        class TList,
 
247
        template <class AtomicType, class Base> class Unit,
 
248
        class Root = EmptyType
 
249
    >
 
250
    class GenLinearHierarchy;
 
251
    
 
252
    template
 
253
    <
 
254
        class T1,
 
255
        class T2,
 
256
        template <class, class> class Unit,
 
257
        class Root
 
258
    >
 
259
    class GenLinearHierarchy<Typelist<T1, T2>, Unit, Root>
 
260
        : public Unit< T1, GenLinearHierarchy<T2, Unit, Root> >
 
261
    {
 
262
    };
 
263
 
 
264
    template
 
265
    <
 
266
        class T,
 
267
        template <class, class> class Unit,
 
268
        class Root
 
269
    >
 
270
    class GenLinearHierarchy<Typelist<T, NullType>, Unit, Root>
 
271
        : public Unit<T, Root>
 
272
    {
 
273
    };
 
274
 
 
275
    template
 
276
    <
 
277
        template <class, class> class Unit,
 
278
        class Root
 
279
    >
 
280
    class GenLinearHierarchy<NullType , Unit, Root>
 
281
        : public Root // is this better: Unit<NullType, Root> ?
 
282
    {
 
283
    };
 
284
 
 
285
#if defined(_MSC_VER) && _MSC_VER >= 1300
 
286
#pragma warning( pop ) 
 
287
#endif
 
288
}   // namespace Loki
 
289
 
 
290
////////////////////////////////////////////////////////////////////////////////
 
291
// Change log:
 
292
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
 
293
// September 16, 2002: Fixed dependent template, using "::template" syntax. T.S.
 
294
//
 
295
// $Log:
 
296
////////////////////////////////////////////////////////////////////////////////
 
297
 
 
298
#endif // HIERARCHYGENERATORS_INC_
 
299
 
 
300
// $Log: HierarchyGenerators.h,v $
 
301
// Revision 1.5  2006/01/16 19:05:09  rich_sposato
 
302
// Added cvs keywords.
 
303
//