Claw
1.7.3
|
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 { 00062 typedef Head head_type; 00063 00065 typedef Queue queue_type; 00066 00067 }; // struct type_list 00068 00076 template<typename Delimiter, typename TypeList> 00077 struct split_type_list_at; 00078 00081 template<typename Delimiter> 00082 struct split_type_list_at<Delimiter, no_type> 00083 { 00085 typedef no_type left_part_type; 00086 00088 typedef no_type right_part_type; 00089 00090 }; // struct split_type_list_at 00091 00099 template<typename Delimiter, typename TypeList> 00100 struct split_type_list_at 00101 { 00103 typedef typename if_then_else 00104 < same_type<Delimiter, typename TypeList::head_type>::result, 00105 no_type, /* delimiter is found, mark the end of the list. */ 00106 type_list /* otherwise, cut in the remaining types. */ 00107 < typename TypeList::head_type, 00108 typename split_type_list_at 00109 <Delimiter, typename TypeList::queue_type>::left_part_type > >::result 00110 left_part_type; 00111 00113 typedef typename if_then_else 00114 < same_type<Delimiter, typename TypeList::head_type>::result, 00115 TypeList, /* delimiter is found, this is the right part. */ 00116 typename split_type_list_at 00117 <Delimiter, typename TypeList::queue_type>::right_part_type >::result 00118 right_part_type; 00119 00120 }; // struct split_type_list_at 00121 00126 template<typename T1> 00127 struct type_list_maker_1 00128 { 00130 typedef type_list<T1, no_type> result; 00131 }; // struct type_list_maker_1 00132 00137 template<typename T1, typename T2> 00138 struct type_list_maker_2 00139 { 00141 typedef type_list< T1, typename type_list_maker_1<T2>::result > result; 00142 }; // struct type_list_maker_2 00143 00148 template<typename T1, typename T2, typename T3> 00149 struct type_list_maker_3 00150 { 00152 typedef 00153 type_list< T1, typename type_list_maker_2<T2, T3>::result > result; 00154 }; // struct type_list_maker_3 00155 00160 template<typename T1, typename T2, typename T3, typename T4> 00161 struct type_list_maker_4 00162 { 00164 typedef 00165 type_list< T1, typename type_list_maker_3<T2, T3, T4>::result > result; 00166 }; // struct type_list_maker_4 00167 00172 template<typename T1, typename T2, typename T3, typename T4, typename T5> 00173 struct type_list_maker_5 00174 { 00176 typedef type_list 00177 < T1, 00178 typename type_list_maker_4<T2, T3, T4, T5>::result > result; 00179 }; // struct type_list_maker_5 00180 00185 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00186 typename T6> 00187 struct type_list_maker_6 00188 { 00190 typedef type_list 00191 < T1, 00192 typename type_list_maker_5<T2, T3, T4, T5, T6>::result > result; 00193 }; // struct type_list_maker_6 00194 00199 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00200 typename T6, typename T7> 00201 struct type_list_maker_7 00202 { 00204 typedef type_list 00205 < T1, 00206 typename type_list_maker_6<T2, T3, T4, T5, T6, T7>::result > result; 00207 }; // struct type_list_maker_7 00208 00213 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00214 typename T6, typename T7, typename T8> 00215 struct type_list_maker_8 00216 { 00218 typedef type_list 00219 < T1, 00220 typename type_list_maker_7<T2, T3, T4, T5, T6, T7, T8>::result > result; 00221 }; // struct type_list_maker_8 00222 00227 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00228 typename T6, typename T7, typename T8, typename T9> 00229 struct type_list_maker_9 00230 { 00232 typedef type_list 00233 < T1, 00234 typename type_list_maker_8 00235 <T2, T3, T4, T5, T6, T7, T8, T9>::result 00236 > result; 00237 }; // struct type_list_maker_9 00238 00243 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00244 typename T6, typename T7, typename T8, typename T9, typename T10> 00245 struct type_list_maker_10 00246 { 00248 typedef type_list 00249 < T1, 00250 typename type_list_maker_9 00251 <T2, T3, T4, T5, T6, T7, T8, T9, T10>::result 00252 > result; 00253 }; // struct type_list_maker_10 00254 00259 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00260 typename T6, typename T7, typename T8, typename T9, typename T10, 00261 typename T11> 00262 struct type_list_maker_11 00263 { 00265 typedef type_list 00266 < T1, 00267 typename type_list_maker_10 00268 <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>::result 00269 > result; 00270 }; // struct type_list_maker_11 00271 00276 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00277 typename T6, typename T7, typename T8, typename T9, typename T10, 00278 typename T11, typename T12> 00279 struct type_list_maker_12 00280 { 00282 typedef type_list 00283 < T1, 00284 typename type_list_maker_11 00285 <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>::result 00286 > result; 00287 }; // struct type_list_maker_12 00288 00293 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00294 typename T6, typename T7, typename T8, typename T9, typename T10, 00295 typename T11, typename T12, typename T13> 00296 struct type_list_maker_13 00297 { 00299 typedef type_list 00300 < T1, 00301 typename type_list_maker_12 00302 <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>::result 00303 > result; 00304 }; // struct type_list_maker_13 00305 00310 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00311 typename T6, typename T7, typename T8, typename T9, typename T10, 00312 typename T11, typename T12, typename T13, typename T14> 00313 struct type_list_maker_14 00314 { 00316 typedef type_list 00317 < T1, 00318 typename type_list_maker_13 00319 <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>::result 00320 > result; 00321 }; // struct type_list_maker_14 00322 00327 template<typename T1, typename T2, typename T3, typename T4, typename T5, 00328 typename T6, typename T7, typename T8, typename T9, typename T10, 00329 typename T11, typename T12, typename T13, typename T14, 00330 typename T15> 00331 struct type_list_maker_15 00332 { 00334 typedef type_list 00335 < T1, 00336 typename type_list_maker_14 00337 <T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::result 00338 > result; 00339 }; // struct type_list_maker_15 00340 00346 template< typename T1, typename T2 = no_type, typename T3 = no_type, 00347 typename T4 = no_type, typename T5 = no_type, 00348 typename T6 = no_type, typename T7 = no_type, 00349 typename T8 = no_type, typename T9 = no_type, 00350 typename T10 = no_type, typename T11 = no_type, 00351 typename T12 = no_type, typename T13 = no_type, 00352 typename T14 = no_type, typename T15 = no_type > 00353 struct type_list_maker 00354 { 00356 typedef typename split_type_list_at 00357 < no_type, 00358 typename type_list_maker_15 00359 < T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, 00360 T15 >::result 00361 >::left_part_type result; 00362 }; // struct type_list_maker 00363 00376 template<typename T, typename List> 00377 struct type_list_find 00378 { 00379 enum 00380 { 00381 result = same_type<T, typename List::head_type>::result 00382 || type_list_find<T, typename List::queue_type>::result 00383 }; 00384 }; // struct type_list_find 00385 00386 template<typename T> 00387 struct type_list_find<T, no_type> 00388 { 00389 enum 00390 { 00391 result = same_type<T, no_type>::result 00392 }; 00393 }; // struct type_list_find 00394 00401 template<typename List> 00402 struct type_list_is_a_set 00403 { 00404 enum 00405 { 00406 result = !type_list_find<typename List::head_type, 00407 typename List::queue_type>::result 00408 && type_list_is_a_set<typename List::queue_type>::result 00409 }; 00410 }; // struct type_list_is_a_set 00411 00412 template<> 00413 struct type_list_is_a_set<no_type> 00414 { 00415 enum 00416 { 00417 result = true 00418 }; 00419 }; // struct type_list_is_a_set [no_type] 00420 00426 template<typename List> 00427 struct type_list_length 00428 { 00429 enum 00430 { 00431 result = 1 + type_list_length<typename List::queue_type>::result 00432 }; 00433 }; // struct type_list_length 00434 00435 template<> 00436 struct type_list_length<no_type> 00437 { 00438 enum 00439 { 00440 result = 0 00441 }; 00442 }; // struct type_list_length [no_type] 00443 00451 template<typename T, typename List> 00452 struct type_list_contains; 00453 00454 template<typename T, typename Tail> 00455 struct type_list_contains< T, type_list<T, Tail> > 00456 { 00457 enum 00458 { 00459 result = true 00460 }; 00461 }; // struct type_list_contains 00462 00463 template<typename T> 00464 struct type_list_contains< T, no_type > 00465 { 00466 enum 00467 { 00468 result = false 00469 }; 00470 }; // struct type_list_contains 00471 00472 template<typename T, typename Head, typename Tail> 00473 struct type_list_contains< T, type_list<Head, Tail> > 00474 { 00475 enum 00476 { 00477 result = type_list_contains<T, Tail>::result 00478 }; 00479 }; // struct type_list_contains 00480 00482 typedef type_list_maker 00483 < signed char, unsigned char, 00484 signed short, unsigned short, 00485 signed int, unsigned int, 00486 signed long, unsigned long, 00487 #ifndef __STRICT_ANSI__ 00488 signed long long, unsigned long long, 00489 #endif 00490 float, 00491 double, 00492 long double, 00493 bool >::result cpp_type_list; 00494 00495 } // namespace meta 00496 } // namespace claw 00497 00498 #endif // __CLAW_TYPE_LIST_HPP__