Claw 1.7.0
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     {
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__