Lumiera  0.pre.03
»edit your freedom«
typelist-manip.hpp
Go to the documentation of this file.
1 /*
2  TYPELIST-MANIP.hpp - Utils for working with lists-of-types
3 
4  Copyright (C) Lumiera.org
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
52 #ifndef LIB_META_TYPELIST_MANIP_H
53 #define LIB_META_TYPELIST_MANIP_H
54 
55 
56 
57 #include "lib/meta/typelist.hpp"
58 
59 #include <sys/types.h>
60 
61 namespace lib {
62 namespace meta {
63 
64 
66  template<class TYPES, size_t i>
67  struct Pick
68  {
69  typedef NullType Type;
70  };
71  template<class TY, class TYPES>
72  struct Pick<Node<TY,TYPES>, 0>
73  {
74  typedef TY Type;
75  };
76  template<class TY, class TYPES, size_t i>
77  struct Pick<Node<TY,TYPES>, i>
78  {
79  typedef typename Pick<TYPES, i-1>::Type Type;
80  };
81 
82 
83 
84 
86  template<class TY, template<class> class _TRANS_>
87  struct Apply { typedef TY List; };
88 
89  template< class TY, class TYPES
90  , template<class> class _TRANS_
91  >
92  struct Apply<Node<TY,TYPES>, _TRANS_ > { typedef Node< typename _TRANS_<TY>::Type
93  , typename Apply<TYPES,_TRANS_>::List
94  > List; };
95 
96 
98  template<bool, class T, class TAIL>
99  struct CondNode { typedef TAIL Next; };
100 
101  template<class T, class TAIL>
102  struct CondNode<true, T, TAIL> { typedef Node<T,TAIL> Next; };
103 
105  template< class TYPES
106  , template<class> class _P_
107  >
108  struct Filter;
109 
110  template<template<class> class _P_>
111  struct Filter<NullType,_P_> { typedef NullType List; };
112 
113  template< class TY, class TYPES
114  , template<class> class _P_
115  >
116  struct Filter<Node<TY,TYPES>,_P_> { typedef typename CondNode< _P_<TY>::value
117  , TY
118  , typename Filter<TYPES,_P_>::List
119  >::Next
120  List; };
121 
122 
124  template<class TY1, class TY2>
126 
127  template< class TY, class TYPES
128  , class TAIL
129  >
130  struct Append<Node<TY,TYPES>, TAIL> { typedef Node<TY, typename Append<TYPES, TAIL>::List> List; };
131 
132  template<class TY, class TYPES>
133  struct Append<NullType, Node<TY,TYPES>> { typedef Node<TY,TYPES> List; };
134 
135  template<class TY, class TYPES>
136  struct Append<Node<TY,TYPES>, NullType> { typedef Node<TY,TYPES> List; };
137 
138  template<class TY1>
139  struct Append<TY1,NullType> { typedef Node<TY1,NullType> List; };
140 
141  template<class TY2>
142  struct Append<NullType,TY2> { typedef Node<TY2,NullType> List; };
143 
144  template<>
145  struct Append<NullType,NullType> { typedef NullType List; };
146 
147 
148 
149 
151  template<class TYPES>
152  struct SplitLast;
153 
154  template<>
155  struct SplitLast<NullType> { typedef NullType Type;
156  typedef NullType List; };
157  template<class TY>
158  struct SplitLast<Node<TY,NullType>> { typedef TY Type;
159  typedef NullType List; };
160 
161  template<class TY, class TYPES>
162  struct SplitLast<Node<TY,TYPES>> { typedef typename SplitLast<TYPES>::Type Type;
163  typedef typename Append< TY,
164  typename SplitLast<TYPES>::List
165  >::List
166  List; };
167 
168 
169 
178  template<class BASE, class OVERLAY, uint i=0>
179  struct Splice;
180 
181  template<class B, class BS,
182  class OVERLAY, uint i>
183  struct Splice<Node<B,BS>, OVERLAY, i> { typedef Node<B, typename Splice<BS, OVERLAY, i-1>::List> List;
184  typedef Node<B, typename Splice<BS, OVERLAY, i-1>::Front> Front;
185  typedef typename Splice<BS, OVERLAY, i-1>::Back Back; };
186 
187  template<class B, class BS,
188  class O, class OS >
189  struct Splice<Node<B,BS>,Node<O,OS>,0> { typedef Node<O, typename Splice<BS,OS, 0>::List> List;
190  typedef NullType Front;
191  typedef typename Splice<BS,OS, 0>::Back Back; };
192 
193  template<class B, class BS>
194  struct Splice<Node<B,BS>, NullType, 0> { typedef Node<B, BS> List;
195  typedef NullType Front;
196  typedef Node<B, BS> Back; };
197 
198  template<class XX, uint i>
199  struct Splice<NullType, XX, i> { typedef NullType List;
200  typedef NullType Front;
201  typedef NullType Back; };
202 
203 
204 
205 
210  template<class TYPES>
211  struct Dissect;
212 
213  template<class T, class TYPES>
214  struct Dissect<Node<T,TYPES>>
215  {
216  typedef Node<T,TYPES> List;
217  typedef T Head;
219  typedef TYPES Tail;
220  typedef typename SplitLast<List>::List Prefix;
221  typedef typename SplitLast<List>::Type End;
223  };
224 
225  template<>
227  {
228  typedef NullType List;
229  typedef NullType Head;
230  typedef NullType First;
231  typedef NullType Tail;
232  typedef NullType Prefix;
233  typedef NullType End;
234  typedef NullType Last;
235  };
236 
237 
238 
239 
244  template<class T, class TY>
246 
247  template<class T>
248  struct PrefixAll<T, NullType> { typedef NullType List; };
249 
250  template<class T>
252 
253  template< class T
254  , class TY, class TYPES
255  >
256  struct PrefixAll<T, Node<TY,TYPES>> { typedef Node< typename Append<T,TY>::List
257  , typename PrefixAll<T,TYPES>::List
258  > List; };
259 
260 
261 
262 
269  template<class TY1,class TY2>
270  struct Distribute { typedef typename PrefixAll<TY1,TY2>::List List; };
271 
272  template<class TY>
273  struct Distribute<NullType,TY> { typedef NullType List; };
274 
275  template< class TY, class TYPES
276  , class TAIL
277  >
278  struct Distribute<Node<TY,TYPES>,TAIL> { typedef typename Append< typename PrefixAll<TY,TAIL>::List
280  >::List
281  List; };
282 
283 
284 
296  template< class X
297  , template<class> class _ENUM_>
300  >::List List; };
301  template< template<class> class _ENUM_>
302  struct Combine<NullType, _ENUM_ > { typedef NodeNull List; };
303 
304  template< class TY, class TYPES
305  , template<class> class _ENUM_>
306  struct Combine<Node<TY,TYPES>,_ENUM_> { typedef typename Distribute< typename _ENUM_<TY>::List
307  , typename Combine<TYPES,_ENUM_>::List
308  >::List List; };
309 
313  template<class F>
314  struct FlagOnOff
315  {
317  };
318 
319 
321  template<class FLAGS>
323  {
324  typedef typename Combine<FLAGS, FlagOnOff>::List List;
325  };
326 
327 
328 
329 
330 }} // namespace lib::meta
331 #endif
TYPES Tail
remainder of the list starting with the second elm.
A template metaprogramming technique for manipulating collections of types.
build all possible combinations, based on a enumeration of the basic cases.
Implementation namespace for support and library code.
SplitLast< List >::Type End
the last element
append lists-of-types
splice a typelist like an overlay into an base typelist, starting at given index. ...
pick the n-th element from a typelist
Node< T, TYPES > List
the complete list
SplitLast< List >::List Prefix
all of the list, up to but excluding the last element
generate all possible on-off combinations of the given flags
conditional node: skip an element based on evaluating a predicate
Node< End, NullType > Last
a list containing the last element
prefix each of the elements, yielding a list-of lists-of-types
access the last list element
filter away those types which don&#39;t fulfil a predicate metafunction
enumeration generator for the Combine metafunction, yielding an "on" and "off" case ...
Node< T, NullType > First
a list containing the first element
build a list-of lists, where each element of the first arg list gets in turn prepended to all element...
Allows to access various parts of a given typelist: Start and End, Prefix and Tail...
apply a transformation (template) to each type in the list