typelist.h

Go to the documentation of this file.
00001 00007 /* 00008 * Copyright © 2000-2002 Sofus Mortensen, Michael Geddes 00009 * 00010 * This material is provided "as is", with absolutely no warranty 00011 * expressed or implied. Any use is at your own risk. Permission to 00012 * use or copy this software for any purpose is hereby granted without 00013 * fee, provided the above notices are retained on all copies. 00014 * Permission to modify the code and to distribute modified code is 00015 * granted, provided the above notices are retained, and a notice that 00016 * the code was modified is included with the above copyright notice. 00017 * 00018 * This header is part of comet. 00019 * http://www.lambdasoft.dk/comet 00020 */ 00021 00022 #ifndef COMET_TYPELIST_H 00023 #define COMET_TYPELIST_H 00024 00025 #include <comet/config.h> 00026 00027 namespace comet { 00028 00032 struct nil {}; 00033 00034 template<typename T, typename U> 00035 struct tl_t { 00036 typedef T head; 00037 typedef U tail; 00038 }; 00039 00040 #ifndef COMET_TL_TRUNC 00041 #ifndef __BORLANDC__ 00042 #define COMET_TL_LIST( X01,X02,X03,X04,X05,X06,X07,X08,X09, \ 00043 X10,X11,X12,X13,X14,X15,X16,X17,X18,X19, \ 00044 X20,X21,X22,X23,X24,X25,X26,X27,X28,X29, \ 00045 X30,X31,X32,X33,X34,X35,X36,X37,X38,X39) \ 00046 X01,X02,X03,X04,X05,X06,X07,X08,X09, \ 00047 X10,X11,X12,X13,X14,X15,X16,X17,X18,X19, \ 00048 X20,X21,X22,X23,X24,X25,X26,X27,X28,X29, \ 00049 X30,X31,X32,X33,X34,X35,X36,X37,X38,X39 00050 #else 00051 #define COMET_TL_LIST( X01,X02,X03,X04,X05,X06,X07,X08,X09, \ 00052 X10,X11,X12,X13,X14,X15,X16,X17,X18,X19, \ 00053 X20,X21,X22,X23,X24,X25,X26,X27,X28,X29, \ 00054 X30,X31,X32,X33,X34,X35,X36,X37,X38,X39) \ 00055 X01,X02,X03,X04,X05,X06,X07,X08,X09, \ 00056 X10,X11,X12,X13,X14,X15,X16,X17,X18,X19, \ 00057 X20,X21,X22,X23,X24,X25,X26,X27,X28,X29 00058 #endif 00059 #else 00060 #define COMET_TL_LIST( X01,X02,X03,X04,X05,X06,X07,X08,X09, \ 00061 X10,X11,X12,X13,X14,X15,X16,X17,X18,X19, \ 00062 X20,X21,X22,X23,X24,X25,X26,X27,X28,X29, \ 00063 X30,X31,X32,X33,X34,X35,X36,X37,X38,X39) \ 00064 X01,X02,X03,X04,X05,X06,X07,X08,X09,X10 00065 #endif 00066 00067 00068 00069 #define COMET_LIST_TEMPLATE \ 00070 typename X00=nil, COMET_TL_LIST( typename X01=nil, typename X02=nil, typename X03=nil, typename X04=nil, \ 00071 typename X05=nil, typename X06=nil, typename X07=nil, typename X08=nil, typename X09=nil, \ 00072 typename X10=nil, typename X11=nil, typename X12=nil, typename X13=nil, typename X14=nil, \ 00073 typename X15=nil, typename X16=nil, typename X17=nil, typename X18=nil, typename X19=nil, \ 00074 typename X20=nil, typename X21=nil, typename X22=nil, typename X23=nil, typename X24=nil, \ 00075 typename X25=nil, typename X26=nil, typename X27=nil, typename X28=nil, typename X29=nil, \ 00076 typename X30=nil, typename X31=nil, typename X32=nil, typename X33=nil, typename X34=nil, \ 00077 typename X35=nil, typename X36=nil, typename X37=nil, typename X38=nil, typename X39=nil) 00078 00079 #define COMET_LIST_TEMPLATE_0 typename X00, COMET_TL_LIST(\ 00080 typename X01, typename X02, typename X03, typename X04, \ 00081 typename X05, typename X06, typename X07, typename X08, typename X09, \ 00082 typename X10, typename X11, typename X12, typename X13, typename X14, \ 00083 typename X15, typename X16, typename X17, typename X18, typename X19, \ 00084 typename X20, typename X21, typename X22, typename X23, typename X24, \ 00085 typename X25, typename X26, typename X27, typename X28, typename X29, \ 00086 typename X30, typename X31, typename X32, typename X33, typename X34, \ 00087 typename X35, typename X36, typename X37, typename X38, typename X39) 00088 00089 #define COMET_LIST_ARG_1 X00, COMET_TL_LIST(\ 00090 X01,X02,X03,X04,X05,X06,X07,X08,X09, \ 00091 X10,X11,X12,X13,X14,X15,X16,X17,X18,X19, \ 00092 X20,X21,X22,X23,X24,X25,X26,X27,X28,X29, \ 00093 X30,X31,X32,X33,X34,X35,X36,X37,X38,X39) 00094 00095 #define COMET_LIST_ARG_0 COMET_TL_LIST(\ 00096 X01,X02,X03,X04,X05,X06,X07,X08,X09, \ 00097 X10,X11,X12,X13,X14,X15,X16,X17,X18,X19, \ 00098 X20,X21,X22,X23,X24,X25,X26,X27,X28,X29, \ 00099 X30,X31,X32,X33,X34,X35,X36,X37,X38,X39) 00100 00101 #define COMET_LIST_NIL nil, COMET_TL_LIST(\ 00102 nil,nil,nil,nil,nil,nil,nil,nil,nil, \ 00103 nil,nil,nil,nil,nil,nil,nil,nil,nil,nil, \ 00104 nil,nil,nil,nil,nil,nil,nil,nil,nil,nil, \ 00105 nil,nil,nil,nil,nil,nil,nil,nil,nil,nil) 00106 00136 template<COMET_LIST_TEMPLATE> struct make_list 00137 { 00138 typedef tl_t<X00, typename make_list<COMET_LIST_ARG_0>::result> result; 00139 }; 00140 00141 template<> struct make_list<COMET_LIST_NIL> 00142 { 00143 typedef nil result; 00144 }; 00145 00146 namespace typelist { 00147 00148 template<typename L> struct length 00149 { 00150 enum { value = 1 + length< typename L::tail>::value }; 00151 }; 00152 00153 template<> struct length<nil> 00154 { 00155 enum { value = 0 }; 00156 }; 00157 00158 #ifdef COMET_PARTIAL_SPECIALISATION 00159 00160 00163 template<typename L, unsigned idx> struct type_at 00164 { 00165 typedef typename type_at<typename L::tail,idx-1>::result result; 00166 }; 00167 template<typename L> struct type_at<L,0> 00168 { 00169 typedef typename L::head result; 00170 }; 00171 template< unsigned idx> struct type_at<nil,idx> 00172 { 00173 typedef nil result; 00174 }; 00175 template<> struct type_at<nil,0> 00176 { 00177 typedef nil result; 00178 }; 00179 00180 00183 template<typename L, typename H, typename T> struct index_of_aux 00184 { 00185 enum { value = 1+(index_of_aux<typename L::tail,typename L::head, T>::value) }; 00186 }; 00187 template< typename L, typename T> struct index_of_aux<L,T,T> 00188 { 00189 enum { value = 0 }; 00190 }; 00194 template<typename L, typename T> struct index_of 00195 { 00196 enum { value = index_of_aux<typename L::tail,typename L::head, T >::value }; 00197 }; 00198 00199 00200 #else 00201 template<typename L, unsigned idx> struct type_at; 00202 00203 template<typename L> struct type_at_aux 00204 { 00205 template<unsigned idx> struct X 00206 { 00207 typedef typename type_at<typename L::tail, idx-1>::result result; 00208 // typedef type_at_aux<typename L::tail>::X<idx-1>::result result; 00209 }; 00210 00211 template<> struct X<0> 00212 { 00213 typedef typename L::head result; 00214 }; 00215 }; 00216 00217 template<> struct type_at_aux<nil> 00218 { 00219 template<unsigned idx> struct X 00220 { 00221 typedef nil result; 00222 }; 00223 }; 00224 00225 00226 /* template<> struct type_at_aux< make_list<> > 00227 { 00228 template<unsigned idx> struct X 00229 { 00230 typedef nil result; 00231 }; 00232 };*/ 00233 00234 template<typename L, unsigned idx> struct type_at 00235 { 00236 typedef typename type_at_aux<L>::X<idx>::result result; 00237 }; 00238 00239 template<typename L, typename T> struct index_of; 00240 00241 template<typename HEAD> struct index_of_aux 00242 { 00243 template<typename TAIL> struct X1 00244 { 00245 template<typename T> struct X2 00246 { 00247 enum { value = 1 + index_of<TAIL, T>::value }; 00248 }; 00249 00250 template<> struct X2<HEAD> 00251 { 00252 enum { value = 0 }; 00253 }; 00254 }; 00255 }; 00256 00257 template<typename L, typename T> struct index_of 00258 { 00259 enum { value = index_of_aux<typename L::head>::X1<typename L::tail>::X2<T>::value }; 00260 }; 00261 #endif // COMET_PARTIAL_SPECIALISATION 00262 00263 #undef COMET_LIST_ARG 00264 00265 #ifdef COMET_PARTIAL_SPECIALISATION 00266 00278 template<typename L1, typename L2> struct append 00279 { 00280 typedef typename L1::head head; 00281 typedef append<typename L1::tail, L2> tail; 00282 }; 00283 00284 template<typename L2> struct append<nil,L2> 00285 { 00286 typedef typename L2::head head; 00287 typedef typename L2::tail tail; 00288 }; 00289 template<typename L2> struct append<make_list<>,L2> 00290 { 00291 typedef typename L2::head head; 00292 typedef typename L2::tail tail; 00293 }; 00294 template<> struct append<nil, nil> 00295 { 00296 typedef nil head; 00297 typedef nil tail; 00298 }; 00299 template<typename L, typename T> struct append_element 00300 { 00301 typedef typename append<L, typename make_list<T>::result>::head head; 00302 typedef typename append<L, typename make_list<T>::result>::tail tail; 00303 }; 00304 #else // COMET_PARTIAL_SPECIALISATION 00305 00306 template<typename L1, typename L2> struct append; 00307 00308 namespace impl { 00309 00310 template<typename L1> struct append_aux 00311 { 00312 template<typename L2> struct with 00313 { 00314 typedef typename L1::head head; 00315 typedef typename append<typename L1::tail, L2> tail; 00316 // typedef typename append_aux<L1::tail>::with<L2> tail; 00317 }; 00318 00319 template<> struct with<nil> 00320 { 00321 typedef typename L1::head head; 00322 typedef typename L1::tail tail; 00323 }; 00324 }; 00325 00326 template<> struct append_aux<nil> 00327 { 00328 template<typename L2> struct with 00329 { 00330 typedef typename L2::head head; 00331 typedef typename L2::tail tail; 00332 }; 00333 }; 00334 00335 /* template<> struct append_aux<make_list<> > 00336 { 00337 template<typename L2> struct with 00338 { 00339 typedef typename L2::head head; 00340 typedef typename L2::tail tail; 00341 }; 00342 };*/ 00343 00344 } 00345 00346 template<typename L1, typename L2> struct append 00347 { 00348 typedef typename impl::append_aux<L1>::with<L2>::head head; 00349 typedef typename impl::append_aux<L1>::with<L2>::tail tail; 00350 }; 00351 00352 template<typename L, typename T> struct append_element 00353 { 00354 typedef typename impl::append_aux<L>::with< typename make_list<T>::result >::head head; 00355 typedef typename impl::append_aux<L>::with< typename make_list<T>::result >::tail tail; 00356 }; 00357 #endif // COMET_PARTIAL_SPECIALISATION 00358 00359 00360 #ifdef COMET_NESTED_TEMPLATES 00361 00370 template< template< typename > class T, typename L1> struct wrap_each; 00371 namespace impl 00372 { 00373 template< template< typename > class T, typename L1> struct wrap_each_aux 00374 { 00375 typedef wrap_each<T, L1> x; 00376 }; 00377 template< template< typename > class T> struct wrap_each_aux< T, nil> 00378 { 00379 typedef nil x; 00380 }; 00381 }; 00382 00383 template< template< typename > class T, typename L1> struct wrap_each 00384 { 00385 typedef T<typename L1::head> head; 00386 typedef typename impl::wrap_each_aux<T, typename L1::tail>::x tail; 00387 }; 00388 00389 template< template< typename > class T> struct wrap_each< T, ::comet::nil > 00390 { 00391 }; 00396 #define COMET_WRAP_EACH_DECLARE(T) 00397 // MSVC7.1 doesn't like this: 00398 // template< template< typename > class T1, typename L1> struct wrap_each; 00399 00405 #define COMET_WRAP_EACH(T, L1) typelist::wrap_each<T, L1> 00406 00407 #else // COMET_NESTED_TEMPLATES 00408 #define COMET_WRAP_EACH_DECLARE(T) \ 00409 template< typename L1 > struct wrap_each_aux##T; \ 00410 namespace impl \ 00411 { \ 00412 template< typename L1> struct p_wrap_each_aux##T \ 00413 { \ 00414 typedef wrap_each_aux##T<L1> x; \ 00415 }; \ 00416 template<> struct p_wrap_each_aux##T <::comet::nil> \ 00417 { \ 00418 typedef ::comet::nil x; \ 00419 }; \ 00420 }; \ 00421 template< typename L1> struct wrap_each_aux##T \ 00422 { \ 00423 typedef T<typename L1::head> head; \ 00424 typedef typename impl::p_wrap_each_aux##T < typename L1::tail>::x tail;\ 00425 }; \ 00426 template<> struct wrap_each_aux##T<::comet::nil> { }; 00427 00428 #define COMET_WRAP_EACH(T, L1) wrap_each_aux##T<L1> 00429 00430 #endif // COMET_NESTED_TEMPLATES 00431 00432 template<typename ITF_LIST> struct ATL_NO_VTABLE inherit_all 00433 : public ITF_LIST::head, public inherit_all<typename ITF_LIST::tail> 00434 {}; 00435 00436 template<> struct inherit_all<nil> {}; 00437 // template<> struct inherit_all<make_list<> > {}; 00438 00439 } 00440 00441 /* MSVC7 chokes on this one - not actually used anywhere 00442 00443 template<int idx, COMET_LIST_TEMPLATE> struct select 00444 { 00445 typedef typelist::type_at< make_list<COMET_LIST_ARG_1>::result, idx>::result result; 00446 };*/ 00447 00448 } // namespace 00449 00450 #endif