KDECore
ktypelistutils.h
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2009 Jonathan Schmidt-Dominé <devel@the-user.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2 as published by the Free Software Foundation, 00007 or - at your option - any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00025 #ifndef KTYPELISTUTILS_H 00026 #define KTYPELISTUTILS_H 00027 00028 #include "ktypelist.h" 00029 #include <cstdlib> 00030 00031 // NO CODE (ignore some preprocessor stuff) 00032 #define NC(...) __VA_ARGS__ 00033 00037 template<class Types, typename Type> 00038 struct KTypeListPush 00039 { 00040 typedef KTypeList<typename Types::Head, typename KTypeListPush<typename Types::Tail, Type>::Result> Result; 00041 }; 00042 00043 template<typename Type> 00044 struct KTypeListPush<KDE::NullType, Type> 00045 { 00046 typedef K_TYPELIST_1(Type) Result; 00047 }; 00048 00052 template<class Types> 00053 struct KTypeListPop 00054 { 00055 typedef KTypeList<typename Types::Head, typename KTypeListPop<typename Types::Tail>::Result> Result; 00056 }; 00057 00058 template<class Type> 00059 struct KTypeListPop<K_TYPELIST_1(Type)> 00060 { 00061 typedef KDE::NullType Result; 00062 }; 00063 00067 template<class Types> 00068 struct KTypeListEnd 00069 { 00070 typedef typename KTypeListEnd<typename Types::Tail>::Result Result; 00071 }; 00072 00073 template<class Type> 00074 struct KTypeListEnd<K_TYPELIST_1(Type)> 00075 { 00076 typedef Type Result; 00077 }; 00078 00082 template<class List1, class List2> 00083 struct KTypeListAppend 00084 { 00085 typedef KTypeList<typename List1::Head, typename KTypeListAppend<typename List1::Tail, List2>::Result> Result; 00086 }; 00087 00088 template<class List2> 00089 struct KTypeListAppend<KDE::NullType, List2> 00090 { 00091 typedef List2 Result; 00092 }; 00093 00097 template<class Types, class Replace> 00098 struct KTypeListReplaceBegin 00099 { 00100 typedef KTypeList<typename Replace::Head, typename KTypeListReplaceBegin<typename Types::Tail, typename Replace::Tail>::Result> Result; 00101 }; 00102 00103 template<class Types> 00104 struct KTypeListReplaceBegin<Types, KDE::NullType> 00105 { 00106 typedef Types Result; 00107 }; 00108 00109 template<class Replace> 00110 struct KTypeListReplaceBegin<KDE::NullType, Replace> 00111 { 00112 typedef KDE::NullType Result; 00113 }; 00114 00118 template<class Types, std::size_t pos> 00119 struct KTypeListAt 00120 { 00121 typedef typename KTypeListAt< 00122 typename Types::Tail, pos - 1>::Result 00123 Result; 00124 }; 00125 00126 template<class Types> 00127 struct KTypeListAt<Types, 0> 00128 { 00129 typedef typename Types::Head Result; 00130 }; 00131 00132 template<std::size_t pos> 00133 struct KTypeListAt<KDE::NullType, pos> 00134 { 00135 }; 00136 00137 template<> 00138 struct KTypeListAt<KDE::NullType, 0> 00139 { 00140 }; 00141 00145 template<class Types, std::size_t pos, typename Default> 00146 struct KTypeListAtWithDefault 00147 { 00148 typedef typename KTypeListAt< 00149 typename Types::Tail, pos - 1>::Result 00150 Result; 00151 }; 00152 00153 template<class Types, typename Default> 00154 struct KTypeListAtWithDefault<Types, 0, Default> 00155 { 00156 typedef typename Types::Head Result; 00157 }; 00158 00159 template<std::size_t pos, typename Default> 00160 struct KTypeListAtWithDefault<KDE::NullType, pos, Default> 00161 { 00162 typedef Default Result; 00163 }; 00164 00165 template<typename Default> 00166 struct KTypeListAtWithDefault<KDE::NullType, 0, Default> 00167 { 00168 typedef Default Result; 00169 }; 00170 00174 template<class Types, template<typename> class Manip> 00175 class KTypeListForeach 00176 { 00177 public: 00178 typedef KTypeList<typename Manip<typename Types::Head>::Result, typename KTypeListForeach<typename Types::Tail, Manip>::Result> Result; 00179 }; 00180 00181 template<template<typename> class Manip> 00182 struct KTypeListForeach<KDE::NullType, Manip> 00183 { 00184 typedef KDE::NullType Result; 00185 }; 00186 00190 template<class Types, typename Type> 00191 struct KTypeListContains 00192 { 00193 enum { value = KTypeListContains<typename Types::Tail, Type>::value }; 00194 }; 00195 00196 template<class Tail, typename Type> 00197 struct KTypeListContains<KTypeList<Type, Tail>, Type> 00198 { 00199 enum { value = true }; 00200 }; 00201 00202 template<typename Type> 00203 struct KTypeListContains<KDE::NullType, Type> 00204 { 00205 enum { value = false }; 00206 }; 00207 00208 namespace KDE 00209 { 00213 template<typename T, typename U> 00214 struct SameTypes 00215 { 00216 enum { value = false }; 00217 }; 00218 00219 template<typename T> 00220 struct SameTypes<T, T> 00221 { 00222 enum { value = true }; 00223 }; 00224 } 00225 00229 #define STATIC_EQUAL(type1, type2) KDE::SameTypes<type1, type2>::value 00230 00234 #define STATIC_FOREACH(list, modifier) typename KTypeListForeach<list, modifier>::Result 00235 00236 namespace KDE 00237 { 00238 template<bool cond, typename T, typename U> 00239 struct IfThenElse 00240 { 00241 typedef T Result; 00242 }; 00243 00244 template<typename T, typename U> 00245 struct IfThenElse<false, T, U> 00246 { 00247 typedef U Result; 00248 }; 00249 00250 template<typename First, typename Second, typename Then, typename Else> 00251 struct IfEqualThenElse 00252 { 00253 typedef Else Result; 00254 }; 00255 00256 template<typename FS, typename Then, typename Else> 00257 struct IfEqualThenElse<FS, FS, Then, Else> 00258 { 00259 typedef Then Result; 00260 }; 00261 } 00262 00266 #define STATIC_IF(expr, T, U) typename KDE::IfThenElse<expr, T, U>::Result 00267 00271 #define STATIC_IF_EQUAL(T, U, V, W) typename KDE::IfEqualThenElse<T, U, V, W>::Result 00272 00273 template<class List, template<typename, typename> class Folder, typename Start = KDE::NullType> 00274 struct KTypeListFold 00275 { 00276 typedef typename KTypeListFold<typename List::Tail, Folder, typename Folder<Start, typename List::Head>::Result>::Result Result; 00277 }; 00278 00279 template<template<typename, typename> class Folder, typename Start> 00280 struct KTypeListFold<KDE::NullType, Folder, Start> 00281 { 00282 typedef Start Result; 00283 }; 00284 00290 #define STATIC_FOLD(List, Modifier, Start) typename KTypeListFold<List, Modifier, Start>::Result 00291 00295 template<class List> 00296 struct KTypeListRevert 00297 { 00298 private: 00299 template<typename Value, typename Current> 00300 struct Impl 00301 { 00302 typedef KTypeList<Current, Value> Result; 00303 }; 00304 public: 00305 typedef STATIC_FOLD(List, Impl, KDE::NullType) Result; 00306 }; 00307 00308 template<class List, typename Pivot, template<typename A, typename B> class Comparator> 00309 class KTypeListAfterPivot 00310 { 00311 template<typename Value, typename Current> 00312 struct Impl 00313 { 00314 typedef STATIC_IF(NC(Comparator<Pivot, Current>::result), NC(KTypeList<Current, Value>), Value) Result; 00315 }; 00316 public: 00317 typedef STATIC_FOLD(List, Impl, KDE::NullType) Result; 00318 }; 00319 00320 template<class List, typename Pivot, template<typename A, typename B> class Comparator> 00321 class KTypeListBeforePivot 00322 { 00323 template<typename Value, typename Current> 00324 struct Impl 00325 { 00326 typedef STATIC_IF(NC(Comparator<Pivot, Current>::result), Value, NC(KTypeList<Current, Value>)) Result; 00327 }; 00328 public: 00329 typedef STATIC_FOLD(List, Impl, KDE::NullType) Result; 00330 }; 00331 00335 template<class List, template<typename A, typename B> class Comparator> 00336 struct KTypeListSort 00337 { 00338 typedef typename KTypeListAppend< 00339 typename KTypeListSort< 00340 typename KTypeListBeforePivot< 00341 typename List::Tail, 00342 typename List::Head, 00343 Comparator>::Result, 00344 Comparator>::Result, 00345 KTypeList< 00346 typename List::Head, 00347 typename KTypeListSort< 00348 typename KTypeListAfterPivot< 00349 typename List::Tail, 00350 typename List::Head, 00351 Comparator>::Result, 00352 Comparator>::Result 00353 > 00354 >::Result Result; 00355 }; 00356 00357 template<template<typename A, typename B> class Comparator> 00358 struct KTypeListSort<KDE::NullType, Comparator> 00359 { 00360 typedef KDE::NullType Result; 00361 }; 00362 00363 #undef NC 00364 00365 #endif
KDE 4.6 API Reference