Claw
1.7.0
|
00001 /* 00002 CLAW - a C++ Library Absolutely Wonderful 00003 00004 CLAW is a free library without any particular aim but being useful to 00005 anyone. 00006 00007 Copyright (C) 2005-2011 Julien Jorge 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public 00020 License along with this library; if not, write to the Free Software 00021 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00022 00023 contact: julien.jorge@gamned.org 00024 */ 00030 #ifndef __CLAW_TYPE_LIST_HPP__ 00031 #define __CLAW_TYPE_LIST_HPP__ 00032 00033 #include <claw/meta/conditional.hpp> 00034 #include <claw/meta/no_type.hpp> 00035 #include <claw/meta/same_type.hpp> 00036 00037 namespace claw 00038 { 00039 namespace meta 00040 { 00058 template<typename Head, typename Queue> 00059 struct type_list 00060 { 00061 typedef Head head_type; 00062 typedef Queue queue_type; 00063 }; // struct type_list 00064 00072 template<typename Delimiter, typename TypeList> 00073 struct split_type_list_at; 00074 00077 template<typename Delimiter> 00078 struct split_type_list_at<Delimiter, no_type> 00079 { 00080 typedef no_type left_part_type; 00081 typedef no_type right_part_type; 00082 00083 }; // struct split_type_list_at 00084 00092 template<typename Delimiter, typename TypeList> 00093 struct split_type_list_at 00094 { 00096 typedef typename if_then_else 00097 < same_type<Delimiter, typename TypeList::head_type>::result, 00098 no_type, /* delimiter is found, mark the end of the list. */ 00099 type_list /* otherwise, cut in the remaining types. */ 00100 < typename TypeList::head_type, 00101 typename split_type_list_at 00102 <Delimiter, typename TypeList::queue_type>::left_part_type > >::result 00103 left_part_type; 00104 00106 typedef typename if_then_else 00107 < same_type<Delimiter, typename TypeList::head_type>::result, 00108 TypeList, /* delimiter is found, this is the right part. */ 00109 typename split_type_list_at 00110 <Delimiter, typename TypeList::queue_type>::right_part_type >::result 00111 right_part_type; 00112 00113 }; // struct split_type_list_at 00114 00119 template<typename T1> 00120 struct type_list_maker_1 00121 { 00122 typedef type_list<T1, no_type> result; 00123 }; // struct type_list_maker_1 00124 00129 template<typename T1, typename T2> 00130 struct type_list_maker_2 00131 { 00132 typedef type_list< T1, typename type_list_maker_1<T2>::result > result; 00133 }; // struct type_list_maker_2 00134 00139 template<typename T1, typename T2, typename T3> 00140 struct type_list_maker_3 00141 { 00142 typedef 00143 type_list< T1, typename type_list_maker_2<T2, T3>::result > result; 00144 }; // struct type_list_maker_3 00145 00150 template<typename T1, typename T2, typename T3, typename T4> 00151 struct type_list_maker_4 00152 { 00153 typedef 00154 type_list< T1, typename type_list_maker_3<T2, T3, T4>::result > result; 00155 }; // struct type_list_maker_4 00156 00161 template<typename T1, typename T2, typename T3, typename T4, typename T5> 00162 struct type_list_maker_5 00163 { 00164 typedef type_list 00165 < T1, 00166 typename type_list_maker_4<T2, T3, T4, T5>::result > result; 00167 }; // struct type_list_maker_5 00168 00173 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00174 typename T6> 00175 struct type_list_maker_6 00176 { 00177 typedef type_list 00178 < T1, 00179 typename type_list_maker_5<T2, T3, T4, T5, T6>::result > result; 00180 }; // struct type_list_maker_6 00181 00186 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00187 typename T6, typename T7> 00188 struct type_list_maker_7 00189 { 00190 typedef type_list 00191 < T1, 00192 typename type_list_maker_6<T2, T3, T4, T5, T6, T7>::result > result; 00193 }; // struct type_list_maker_7 00194 00199 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00200 typename T6, typename T7, typename T8> 00201 struct type_list_maker_8 00202 { 00203 typedef type_list 00204 < T1, 00205 typename type_list_maker_7<T2, T3, T4, T5, T6, T7, T8>::result > result; 00206 }; // struct type_list_maker_8 00207 00212 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00213 typename T6, typename T7, typename T8, typename T9> 00214 struct type_list_maker_9 00215 { 00216 typedef type_list 00217 < T1, 00218 typename type_list_maker_8 00219 <T2, T3, T4, T5, T6, T7, T8, T9>::result 00220 > result; 00221 }; // struct type_list_maker_9 00222 00227 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00228 typename T6, typename T7, typename T8, typename T9, typename T10> 00229 struct type_list_maker_10 00230 { 00231 typedef type_list 00232 < T1, 00233 typename type_list_maker_9 00234 <T2, T3, T4, T5, T6, T7, T8, T9, T10>::result 00235 > result; 00236 }; // struct type_list_maker_10 00237 00242 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00243 typename T6, typename T7, typename T8, typename T9, typename T10, 00244 typename T11> 00245 struct type_list_maker_11 00246 { 00247 typedef type_list 00248 < T1, 00249 typename type_list_maker_10 00250 <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>::result 00251 > result; 00252 }; // struct type_list_maker_11 00253 00258 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00259 typename T6, typename T7, typename T8, typename T9, typename T10, 00260 typename T11, typename T12> 00261 struct type_list_maker_12 00262 { 00263 typedef type_list 00264 < T1, 00265 typename type_list_maker_11 00266 <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>::result 00267 > result; 00268 }; // struct type_list_maker_12 00269 00274 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00275 typename T6, typename T7, typename T8, typename T9, typename T10, 00276 typename T11, typename T12, typename T13> 00277 struct type_list_maker_13 00278 { 00279 typedef type_list 00280 < T1, 00281 typename type_list_maker_12 00282 <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>::result 00283 > result; 00284 }; // struct type_list_maker_13 00285 00290 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00291 typename T6, typename T7, typename T8, typename T9, typename T10, 00292 typename T11, typename T12, typename T13, typename T14> 00293 struct type_list_maker_14 00294 { 00295 typedef type_list 00296 < T1, 00297 typename type_list_maker_13 00298 <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>::result 00299 > result; 00300 }; // struct type_list_maker_14 00301 00306 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00307 typename T6, typename T7, typename T8, typename T9, typename T10, 00308 typename T11, typename T12, typename T13, typename T14, 00309 typename T15> 00310 struct type_list_maker_15 00311 { 00312 typedef type_list 00313 < T1, 00314 typename type_list_maker_14 00315 <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::result 00316 > result; 00317 }; // struct type_list_maker_15 00318 00324 template< typename T1, typename T2 = no_type, typename T3 = no_type, 00325 typename T4 = no_type, typename T5 = no_type, 00326 typename T6 = no_type, typename T7 = no_type, 00327 typename T8 = no_type, typename T9 = no_type, 00328 typename T10 = no_type, typename T11 = no_type, 00329 typename T12 = no_type, typename T13 = no_type, 00330 typename T14 = no_type, typename T15 = no_type > 00331 struct type_list_maker 00332 { 00333 typedef typename split_type_list_at 00334 < no_type, 00335 typename type_list_maker_15 00336 < T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, 00337 T15 >::result 00338 >::left_part_type result; 00339 }; // struct type_list_maker 00340 00353 template<typename T, typename List> 00354 struct type_list_find 00355 { 00356 enum 00357 { 00358 result = same_type<T, typename List::head_type>::result 00359 || type_list_find<T, typename List::queue_type>::result 00360 }; 00361 }; // struct type_list_find 00362 00363 template<typename T> 00364 struct type_list_find<T, no_type> 00365 { 00366 enum 00367 { 00368 result = same_type<T, no_type>::result 00369 }; 00370 }; // struct type_list_find 00371 00378 template<typename List> 00379 struct type_list_is_a_set 00380 { 00381 enum 00382 { 00383 result = !type_list_find<typename List::head_type, 00384 typename List::queue_type>::result 00385 && type_list_is_a_set<typename List::queue_type>::result 00386 }; 00387 }; // struct type_list_is_a_set 00388 00389 template<> 00390 struct type_list_is_a_set<no_type> 00391 { 00392 enum 00393 { 00394 result = true 00395 }; 00396 }; // struct type_list_is_a_set [no_type] 00397 00403 template<typename List> 00404 struct type_list_length 00405 { 00406 enum 00407 { 00408 result = 1 + type_list_length<typename List::queue_type>::result 00409 }; 00410 }; // struct type_list_length 00411 00412 template<> 00413 struct type_list_length<no_type> 00414 { 00415 enum 00416 { 00417 result = 0 00418 }; 00419 }; // struct type_list_length [no_type] 00420 00428 template<typename T, typename List> 00429 struct type_list_contains; 00430 00431 template<typename T, typename Tail> 00432 struct type_list_contains< T, type_list<T, Tail> > 00433 { 00434 enum 00435 { 00436 result = true 00437 }; 00438 }; // struct type_list_contains 00439 00440 template<typename T> 00441 struct type_list_contains< T, no_type > 00442 { 00443 enum 00444 { 00445 result = false 00446 }; 00447 }; // struct type_list_contains 00448 00449 template<typename T, typename Head, typename Tail> 00450 struct type_list_contains< T, type_list<Head, Tail> > 00451 { 00452 enum 00453 { 00454 result = type_list_contains<T, Tail>::result 00455 }; 00456 }; // struct type_list_contains 00457 00459 typedef type_list_maker 00460 < signed char, unsigned char, 00461 signed short, unsigned short, 00462 signed int, unsigned int, 00463 signed long, unsigned long, 00464 signed long long, unsigned long long, 00465 float, 00466 double, 00467 long double, 00468 bool >::result cpp_type_list; 00469 00470 } // namespace meta 00471 } // namespace claw 00472 00473 #endif // __CLAW_TYPE_LIST_HPP__