Claw  1.7.3
meta/type_list.hpp
Go to the documentation of this file.
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__