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)
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
43 #ifndef LIB_META_TYPELIST_MANIP_H
44 #define LIB_META_TYPELIST_MANIP_H
45 
46 
47 
48 #include "lib/meta/typelist.hpp"
49 
50 #include <sys/types.h>
51 
52 namespace lib {
53 namespace meta {
54 
55 
57  template<class TYPES, size_t i>
58  struct Pick
59  {
60  typedef NullType Type;
61  };
62  template<class TY, class TYPES>
63  struct Pick<Node<TY,TYPES>, 0>
64  {
65  typedef TY Type;
66  };
67  template<class TY, class TYPES, size_t i>
68  struct Pick<Node<TY,TYPES>, i>
69  {
70  typedef typename Pick<TYPES, i-1>::Type Type;
71  };
72 
73 
74 
75 
77  template<class TY, template<class> class _TRANS_>
78  struct Apply { typedef TY List; };
79 
80  template< class TY, class TYPES
81  , template<class> class _TRANS_
82  >
83  struct Apply<Node<TY,TYPES>, _TRANS_ > { typedef Node< typename _TRANS_<TY>::Type
84  , typename Apply<TYPES,_TRANS_>::List
85  > List; };
86 
87 
89  template<bool, class T, class TAIL>
90  struct CondNode { typedef TAIL Next; };
91 
92  template<class T, class TAIL>
93  struct CondNode<true, T, TAIL> { typedef Node<T,TAIL> Next; };
94 
96  template< class TYPES
97  , template<class> class _P_
98  >
99  struct Filter;
100 
101  template<template<class> class _P_>
102  struct Filter<NullType,_P_> { typedef NullType List; };
103 
104  template< class TY, class TYPES
105  , template<class> class _P_
106  >
107  struct Filter<Node<TY,TYPES>,_P_> { typedef typename CondNode< _P_<TY>::value
108  , TY
109  , typename Filter<TYPES,_P_>::List
110  >::Next
111  List; };
112 
113 
115  template<class TY1, class TY2>
117 
118  template< class TY, class TYPES
119  , class TAIL
120  >
121  struct Append<Node<TY,TYPES>, TAIL> { typedef Node<TY, typename Append<TYPES, TAIL>::List> List; };
122 
123  template<class TY, class TYPES>
124  struct Append<NullType, Node<TY,TYPES>> { typedef Node<TY,TYPES> List; };
125 
126  template<class TY, class TYPES>
127  struct Append<Node<TY,TYPES>, NullType> { typedef Node<TY,TYPES> List; };
128 
129  template<class TY1>
130  struct Append<TY1,NullType> { typedef Node<TY1,NullType> List; };
131 
132  template<class TY2>
133  struct Append<NullType,TY2> { typedef Node<TY2,NullType> List; };
134 
135  template<>
136  struct Append<NullType,NullType> { typedef NullType List; };
137 
138 
139 
140 
142  template<class TYPES>
143  struct SplitLast;
144 
145  template<>
146  struct SplitLast<NullType> { typedef NullType Type;
147  typedef NullType List; };
148  template<class TY>
149  struct SplitLast<Node<TY,NullType>> { typedef TY Type;
150  typedef NullType List; };
151 
152  template<class TY, class TYPES>
153  struct SplitLast<Node<TY,TYPES>> { typedef typename SplitLast<TYPES>::Type Type;
154  typedef typename Append< TY,
155  typename SplitLast<TYPES>::List
156  >::List
157  List; };
158 
159 
160 
169  template<class BASE, class OVERLAY, uint i=0>
170  struct Splice;
171 
172  template<class B, class BS,
173  class OVERLAY, uint i>
174  struct Splice<Node<B,BS>, OVERLAY, i> { typedef Node<B, typename Splice<BS, OVERLAY, i-1>::List> List;
175  typedef Node<B, typename Splice<BS, OVERLAY, i-1>::Front> Front;
176  typedef typename Splice<BS, OVERLAY, i-1>::Back Back; };
177 
178  template<class B, class BS,
179  class O, class OS >
180  struct Splice<Node<B,BS>,Node<O,OS>,0> { typedef Node<O, typename Splice<BS,OS, 0>::List> List;
181  typedef NullType Front;
182  typedef typename Splice<BS,OS, 0>::Back Back; };
183 
184  template<class B, class BS>
185  struct Splice<Node<B,BS>, NullType, 0> { typedef Node<B, BS> List;
186  typedef NullType Front;
187  typedef Node<B, BS> Back; };
188 
189  template<class XX, uint i>
190  struct Splice<NullType, XX, i> { typedef NullType List;
191  typedef NullType Front;
192  typedef NullType Back; };
193 
194 
195 
196 
201  template<class TYPES>
202  struct Dissect;
203 
204  template<class T, class TYPES>
205  struct Dissect<Node<T,TYPES>>
206  {
207  typedef Node<T,TYPES> List;
208  typedef T Head;
210  typedef TYPES Tail;
211  typedef typename SplitLast<List>::List Prefix;
212  typedef typename SplitLast<List>::Type End;
214  };
215 
216  template<>
218  {
219  typedef NullType List;
220  typedef NullType Head;
221  typedef NullType First;
222  typedef NullType Tail;
223  typedef NullType Prefix;
224  typedef NullType End;
225  typedef NullType Last;
226  };
227 
228 
229 
230 
235  template<class T, class TY>
237 
238  template<class T>
239  struct PrefixAll<T, NullType> { typedef NullType List; };
240 
241  template<class T>
243 
244  template< class T
245  , class TY, class TYPES
246  >
247  struct PrefixAll<T, Node<TY,TYPES>> { typedef Node< typename Append<T,TY>::List
248  , typename PrefixAll<T,TYPES>::List
249  > List; };
250 
251 
252 
253 
260  template<class TY1,class TY2>
261  struct Distribute { typedef typename PrefixAll<TY1,TY2>::List List; };
262 
263  template<class TY>
264  struct Distribute<NullType,TY> { typedef NullType List; };
265 
266  template< class TY, class TYPES
267  , class TAIL
268  >
269  struct Distribute<Node<TY,TYPES>,TAIL> { typedef typename Append< typename PrefixAll<TY,TAIL>::List
271  >::List
272  List; };
273 
274 
275 
287  template< class X
288  , template<class> class _ENUM_>
291  >::List List; };
292  template< template<class> class _ENUM_>
293  struct Combine<NullType, _ENUM_ > { typedef NodeNull List; };
294 
295  template< class TY, class TYPES
296  , template<class> class _ENUM_>
297  struct Combine<Node<TY,TYPES>,_ENUM_> { typedef typename Distribute< typename _ENUM_<TY>::List
298  , typename Combine<TYPES,_ENUM_>::List
299  >::List List; };
300 
304  template<class F>
305  struct FlagOnOff
306  {
308  };
309 
310 
312  template<class FLAGS>
314  {
315  typedef typename Combine<FLAGS, FlagOnOff>::List List;
316  };
317 
318 
319 
320 
321 }} // namespace lib::meta
322 #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