00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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 };
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 };
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,
00099 type_list
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,
00109 typename split_type_list_at
00110 <Delimiter, typename TypeList::queue_type>::right_part_type >::result
00111 right_part_type;
00112
00113 };
00114
00119 template<typename T1>
00120 struct type_list_maker_1
00121 {
00122 typedef type_list<T1, no_type> result;
00123 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
00245
00246 template<>
00247 struct type_list_is_a_set<no_type>
00248 {
00249 enum
00250 {
00251 result = true
00252 };
00253 };
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 };
00268
00269 template<>
00270 struct type_list_length<no_type>
00271 {
00272 enum
00273 {
00274 result = 0
00275 };
00276 };
00277
00278 }
00279 }
00280
00281 #endif // __CLAW_TYPE_LIST_HPP__