CLAW Library (a C++ Library Absolutely Wonderful) 1.5.5
|
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-2010 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@yahoo.fr 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 00187 template< typename T1, typename T2 = no_type, typename T3 = no_type, 00188 typename T4 = no_type, typename T5 = no_type, 00189 typename T6 = no_type > 00190 struct type_list_maker 00191 { 00192 typedef typename split_type_list_at 00193 < no_type, 00194 typename type_list_maker_6<T1, T2, T3, T4, T5, T6>::result 00195 >::left_part_type result; 00196 }; // struct type_list_maker 00197 00210 template<typename T, typename List> 00211 struct type_list_find 00212 { 00213 enum 00214 { 00215 result = same_type<T, typename List::head_type>::result 00216 || type_list_find<T, typename List::queue_type>::result 00217 }; 00218 }; // struct type_list_find 00219 00220 template<typename T> 00221 struct type_list_find<T, no_type> 00222 { 00223 enum 00224 { 00225 result = same_type<T, no_type>::result 00226 }; 00227 }; // struct type_list_find 00228 00235 template<typename List> 00236 struct type_list_is_a_set 00237 { 00238 enum 00239 { 00240 result = !type_list_find<typename List::head_type, 00241 typename List::queue_type>::result 00242 && type_list_is_a_set<typename List::queue_type>::result 00243 }; 00244 }; // struct type_list_is_a_set 00245 00246 template<> 00247 struct type_list_is_a_set<no_type> 00248 { 00249 enum 00250 { 00251 result = true 00252 }; 00253 }; // struct type_list_is_a_set [no_type] 00254 00260 template<typename List> 00261 struct type_list_length 00262 { 00263 enum 00264 { 00265 result = 1 + type_list_length<typename List::queue_type>::result 00266 }; 00267 }; // struct type_list_length 00268 00269 template<> 00270 struct type_list_length<no_type> 00271 { 00272 enum 00273 { 00274 result = 0 00275 }; 00276 }; // struct type_list_length [no_type] 00277 00278 } // namespace meta 00279 } // namespace claw 00280 00281 #endif // __CLAW_TYPE_LIST_HPP__