CLAW Library (a C++ Library Absolutely Wonderful) 1.5.5

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-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__