root / Community Core Vision / Linux / libs / poco / include / Poco / TypeList.h @ 9
View | Annotate | Download (10.7 KB)
| 1 | //
|
|---|---|
| 2 | // TypeList.h
|
| 3 | //
|
| 4 | // $Id: //poco/1.3/Foundation/include/Poco/TypeList.h#6 $
|
| 5 | //
|
| 6 | // Library: Foundation
|
| 7 | // Package: Core
|
| 8 | // Module: TypeList
|
| 9 | //
|
| 10 | // Implementation of the TypeList template.
|
| 11 | //
|
| 12 | // Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
| 13 | // and Contributors.
|
| 14 | //
|
| 15 | // Portions extracted and adapted from
|
| 16 | // The Loki Library
|
| 17 | // Copyright (c) 2001 by Andrei Alexandrescu
|
| 18 | //
|
| 19 | // Permission is hereby granted, free of charge, to any person or organization
|
| 20 | // obtaining a copy of the software and accompanying documentation covered by
|
| 21 | // this license (the "Software") to use, reproduce, display, distribute,
|
| 22 | // execute, and transmit the Software, and to prepare derivative works of the
|
| 23 | // Software, and to permit third-parties to whom the Software is furnished to
|
| 24 | // do so, all subject to the following:
|
| 25 | //
|
| 26 | // The copyright notices in the Software and this entire statement, including
|
| 27 | // the above license grant, this restriction and the following disclaimer,
|
| 28 | // must be included in all copies of the Software, in whole or in part, and
|
| 29 | // all derivative works of the Software, unless such copies or derivative
|
| 30 | // works are solely in the form of machine-executable object code generated by
|
| 31 | // a source language processor.
|
| 32 | //
|
| 33 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 34 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 35 | // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
| 36 | // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
| 37 | // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
| 38 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
| 39 | // DEALINGS IN THE SOFTWARE.
|
| 40 | //
|
| 41 | |
| 42 | |
| 43 | #ifndef Foundation_TypeList_INCLUDED
|
| 44 | #define Foundation_TypeList_INCLUDED
|
| 45 | |
| 46 | |
| 47 | #include "Poco/Foundation.h" |
| 48 | #include "Poco/MetaProgramming.h" |
| 49 | |
| 50 | |
| 51 | namespace Poco {
|
| 52 | |
| 53 | |
| 54 | template <class Head, class Tail> |
| 55 | struct TypeList;
|
| 56 | |
| 57 | |
| 58 | struct NullTypeList
|
| 59 | {
|
| 60 | enum
|
| 61 | {
|
| 62 | length = 0
|
| 63 | }; |
| 64 | |
| 65 | bool operator == (const NullTypeList&) const |
| 66 | {
|
| 67 | return true; |
| 68 | } |
| 69 | |
| 70 | bool operator != (const NullTypeList&) const |
| 71 | {
|
| 72 | return false; |
| 73 | } |
| 74 | |
| 75 | bool operator < (const NullTypeList&) const |
| 76 | {
|
| 77 | return false; |
| 78 | } |
| 79 | }; |
| 80 | |
| 81 | |
| 82 | template <class Head, class Tail> |
| 83 | struct TypeList
|
| 84 | /// Compile Time List of Types
|
| 85 | {
|
| 86 | typedef Head HeadType;
|
| 87 | typedef Tail TailType;
|
| 88 | typedef typename TypeWrapper<HeadType>::CONSTTYPE ConstHeadType;
|
| 89 | typedef typename TypeWrapper<TailType>::CONSTTYPE ConstTailType;
|
| 90 | enum
|
| 91 | {
|
| 92 | length = TailType::length+1
|
| 93 | }; |
| 94 | |
| 95 | TypeList():head(), tail() |
| 96 | {
|
| 97 | } |
| 98 | |
| 99 | TypeList(ConstHeadType& h, ConstTailType& t):head(h), tail(t) |
| 100 | {
|
| 101 | } |
| 102 | |
| 103 | TypeList(const TypeList& tl): head(tl.head), tail(tl.tail)
|
| 104 | {
|
| 105 | } |
| 106 | |
| 107 | TypeList& operator = (const TypeList& tl)
|
| 108 | {
|
| 109 | if (this != &tl)
|
| 110 | {
|
| 111 | TypeList tmp(tl); |
| 112 | swap(tmp); |
| 113 | } |
| 114 | return *this;
|
| 115 | } |
| 116 | |
| 117 | bool operator == (const TypeList& tl) const |
| 118 | {
|
| 119 | return tl.head == head && tl.tail == tail;
|
| 120 | } |
| 121 | |
| 122 | bool operator != (const TypeList& tl) const |
| 123 | {
|
| 124 | return !(*this == tl);
|
| 125 | } |
| 126 | |
| 127 | bool operator < (const TypeList& tl) const |
| 128 | {
|
| 129 | if (head < tl.head)
|
| 130 | return true; |
| 131 | else if (head == tl.head) |
| 132 | return tail < tl.tail;
|
| 133 | return false; |
| 134 | } |
| 135 | |
| 136 | void swap(TypeList& tl)
|
| 137 | {
|
| 138 | std::swap(head, tl.head); |
| 139 | std::swap(tail, tl.tail); |
| 140 | } |
| 141 | |
| 142 | HeadType head; |
| 143 | TailType tail; |
| 144 | }; |
| 145 | |
| 146 | |
| 147 | template <typename T0 = NullTypeList, |
| 148 | typename T1 = NullTypeList, |
| 149 | typename T2 = NullTypeList, |
| 150 | typename T3 = NullTypeList, |
| 151 | typename T4 = NullTypeList, |
| 152 | typename T5 = NullTypeList, |
| 153 | typename T6 = NullTypeList, |
| 154 | typename T7 = NullTypeList, |
| 155 | typename T8 = NullTypeList, |
| 156 | typename T9 = NullTypeList, |
| 157 | typename T10 = NullTypeList, |
| 158 | typename T11 = NullTypeList, |
| 159 | typename T12 = NullTypeList, |
| 160 | typename T13 = NullTypeList, |
| 161 | typename T14 = NullTypeList, |
| 162 | typename T15 = NullTypeList, |
| 163 | typename T16 = NullTypeList, |
| 164 | typename T17 = NullTypeList, |
| 165 | typename T18 = NullTypeList, |
| 166 | typename T19 = NullTypeList> |
| 167 | struct TypeListType
|
| 168 | /// TypeListType takes 1 - 20 typename arguments.
|
| 169 | /// Usage:
|
| 170 | ///
|
| 171 | /// TypeListType<T0, T1, ... , Tn>::HeadType typeList;
|
| 172 | ///
|
| 173 | /// typeList is a TypeList of T0, T1, ... , Tn
|
| 174 | {
|
| 175 | private:
|
| 176 | typedef typename TypeListType<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19>::HeadType TailType;
|
| 177 | |
| 178 | public:
|
| 179 | typedef TypeList<T0, TailType> HeadType;
|
| 180 | }; |
| 181 | |
| 182 | |
| 183 | template <> |
| 184 | struct TypeListType<>
|
| 185 | {
|
| 186 | typedef NullTypeList HeadType;
|
| 187 | }; |
| 188 | |
| 189 | |
| 190 | template <int n>
|
| 191 | struct Getter
|
| 192 | {
|
| 193 | template <class Ret, class Head, class Tail> |
| 194 | inline static Ret& get(TypeList<Head, Tail>& val) |
| 195 | {
|
| 196 | return Getter<n-1>::template get<Ret, typename Tail::HeadType, typename Tail::TailType>(val.tail); |
| 197 | } |
| 198 | |
| 199 | template <class Ret, class Head, class Tail> |
| 200 | inline static const Ret& get(const TypeList<Head, Tail>& val) |
| 201 | {
|
| 202 | return Getter<n-1>::template get<Ret, typename Tail::HeadType, typename Tail::TailType>(val.tail); |
| 203 | } |
| 204 | }; |
| 205 | |
| 206 | |
| 207 | template <> |
| 208 | struct Getter<0> |
| 209 | {
|
| 210 | template <class Ret, class Head, class Tail> |
| 211 | inline static Ret& get(TypeList<Head, Tail>& val) |
| 212 | {
|
| 213 | return val.head;
|
| 214 | } |
| 215 | |
| 216 | template <class Ret, class Head, class Tail> |
| 217 | inline static const Ret& get(const TypeList<Head, Tail>& val) |
| 218 | {
|
| 219 | return val.head;
|
| 220 | } |
| 221 | }; |
| 222 | |
| 223 | |
| 224 | template <int N, class Head>
|
| 225 | struct TypeGetter;
|
| 226 | |
| 227 | |
| 228 | template <int N, class Head, class Tail>
|
| 229 | struct TypeGetter<N, TypeList<Head, Tail> >
|
| 230 | {
|
| 231 | typedef typename TypeGetter<N-1, Tail>::HeadType HeadType; |
| 232 | typedef typename TypeWrapper<HeadType>::CONSTTYPE ConstHeadType;
|
| 233 | }; |
| 234 | |
| 235 | |
| 236 | template <class Head, class Tail> |
| 237 | struct TypeGetter<0, TypeList<Head, Tail> > |
| 238 | {
|
| 239 | typedef typename TypeList<Head, Tail>::HeadType HeadType;
|
| 240 | typedef typename TypeWrapper<HeadType>::CONSTTYPE ConstHeadType;
|
| 241 | }; |
| 242 | |
| 243 | |
| 244 | template <class Head, class T> |
| 245 | struct TypeLocator;
|
| 246 | /// TypeLocator returns the first occurrence of the type T in Head
|
| 247 | /// or -1 if the type is not found.
|
| 248 | ///
|
| 249 | /// Usage example:
|
| 250 | ///
|
| 251 | /// TypeLocator<Head, int>::HeadType TypeLoc;
|
| 252 | ///
|
| 253 | /// if (2 == TypeLoc.value) ...
|
| 254 | ///
|
| 255 | |
| 256 | |
| 257 | template <class T> |
| 258 | struct TypeLocator<NullTypeList, T>
|
| 259 | {
|
| 260 | enum { value = -1 }; |
| 261 | }; |
| 262 | |
| 263 | |
| 264 | template <class T, class Tail> |
| 265 | struct TypeLocator<TypeList<T, Tail>, T>
|
| 266 | {
|
| 267 | enum { value = 0 }; |
| 268 | }; |
| 269 | |
| 270 | |
| 271 | template <class Head, class Tail, class T> |
| 272 | struct TypeLocator<TypeList<Head, Tail>, T>
|
| 273 | {
|
| 274 | private:
|
| 275 | enum { tmp = TypeLocator<Tail, T>::value };
|
| 276 | public:
|
| 277 | enum { value = tmp == -1 ? -1 : 1 + tmp }; |
| 278 | }; |
| 279 | |
| 280 | |
| 281 | template <class Head, class T> |
| 282 | struct TypeAppender;
|
| 283 | /// TypeAppender appends T (type or a TypeList) to Head.
|
| 284 | ///
|
| 285 | /// Usage:
|
| 286 | ///
|
| 287 | /// typedef TypeListType<char>::HeadType Type1;
|
| 288 | /// typedef TypeAppender<Type1, int>::HeadType Type2;
|
| 289 | /// (Type2 is a TypeList of char,int)
|
| 290 | ///
|
| 291 | /// typedef TypeListType<float, double>::HeadType Type3;
|
| 292 | /// typedef TypeAppender<Type2, Type3>::HeadType Type4;
|
| 293 | /// (Type4 is a TypeList of char,int,float,double)
|
| 294 | ///
|
| 295 | |
| 296 | |
| 297 | template <> |
| 298 | struct TypeAppender<NullTypeList, NullTypeList>
|
| 299 | {
|
| 300 | typedef NullTypeList HeadType;
|
| 301 | }; |
| 302 | |
| 303 | |
| 304 | template <class T> |
| 305 | struct TypeAppender<NullTypeList, T>
|
| 306 | {
|
| 307 | typedef TypeList<T, NullTypeList> HeadType;
|
| 308 | }; |
| 309 | |
| 310 | |
| 311 | template <class Head, class Tail> |
| 312 | struct TypeAppender<NullTypeList, TypeList<Head, Tail> >
|
| 313 | {
|
| 314 | typedef TypeList<Head, Tail> HeadType;
|
| 315 | }; |
| 316 | |
| 317 | |
| 318 | template <class Head, class Tail, class T> |
| 319 | struct TypeAppender<TypeList<Head, Tail>, T>
|
| 320 | {
|
| 321 | typedef TypeList<Head, typename TypeAppender<Tail, T>::HeadType> HeadType;
|
| 322 | }; |
| 323 | |
| 324 | |
| 325 | template <class Head, class T> |
| 326 | struct TypeOneEraser;
|
| 327 | /// TypeOneEraser erases the first occurence of the type T in Head.
|
| 328 | /// Usage:
|
| 329 | ///
|
| 330 | /// typedef TypeListType<char, int, float>::HeadType Type3;
|
| 331 | /// typedef TypeOneEraser<Type3, int>::HeadType Type2;
|
| 332 | /// (Type2 is a TypeList of char,float)
|
| 333 | ///
|
| 334 | |
| 335 | |
| 336 | template <class T> |
| 337 | struct TypeOneEraser<NullTypeList, T>
|
| 338 | {
|
| 339 | typedef NullTypeList HeadType;
|
| 340 | }; |
| 341 | |
| 342 | |
| 343 | template <class T, class Tail> |
| 344 | struct TypeOneEraser<TypeList<T, Tail>, T>
|
| 345 | {
|
| 346 | typedef Tail HeadType;
|
| 347 | }; |
| 348 | |
| 349 | |
| 350 | template <class Head, class Tail, class T> |
| 351 | struct TypeOneEraser<TypeList<Head, Tail>, T>
|
| 352 | {
|
| 353 | typedef TypeList <Head, typename TypeOneEraser<Tail, T>::HeadType> HeadType;
|
| 354 | }; |
| 355 | |
| 356 | |
| 357 | template <class Head, class T> |
| 358 | struct TypeAllEraser;
|
| 359 | /// TypeAllEraser erases all the occurences of the type T in Head.
|
| 360 | /// Usage:
|
| 361 | ///
|
| 362 | /// typedef TypeListType<char, int, float, int>::HeadType Type4;
|
| 363 | /// typedef TypeAllEraser<Type4, int>::HeadType Type2;
|
| 364 | /// (Type2 is a TypeList of char,float)
|
| 365 | ///
|
| 366 | |
| 367 | |
| 368 | template <class T> |
| 369 | struct TypeAllEraser<NullTypeList, T>
|
| 370 | {
|
| 371 | typedef NullTypeList HeadType;
|
| 372 | }; |
| 373 | |
| 374 | |
| 375 | template <class T, class Tail> |
| 376 | struct TypeAllEraser<TypeList<T, Tail>, T>
|
| 377 | {
|
| 378 | typedef typename TypeAllEraser<Tail, T>::HeadType HeadType;
|
| 379 | }; |
| 380 | |
| 381 | |
| 382 | template <class Head, class Tail, class T> |
| 383 | struct TypeAllEraser<TypeList<Head, Tail>, T>
|
| 384 | {
|
| 385 | typedef TypeList <Head, typename TypeAllEraser<Tail, T>::HeadType> HeadType;
|
| 386 | }; |
| 387 | |
| 388 | |
| 389 | template <class Head> |
| 390 | struct TypeDuplicateEraser;
|
| 391 | /// TypeDuplicateEraser erases all but the first occurence of the type T in Head.
|
| 392 | /// Usage:
|
| 393 | ///
|
| 394 | /// typedef TypeListType<char, int, float, int>::HeadType Type4;
|
| 395 | /// typedef TypeDuplicateEraser<Type4, int>::HeadType Type3;
|
| 396 | /// (Type3 is a TypeList of char,int,float)
|
| 397 | ///
|
| 398 | |
| 399 | |
| 400 | template <> |
| 401 | struct TypeDuplicateEraser<NullTypeList>
|
| 402 | {
|
| 403 | typedef NullTypeList HeadType;
|
| 404 | }; |
| 405 | |
| 406 | |
| 407 | template <class Head, class Tail> |
| 408 | struct TypeDuplicateEraser<TypeList<Head, Tail> >
|
| 409 | {
|
| 410 | private:
|
| 411 | typedef typename TypeDuplicateEraser<Tail>::HeadType L1;
|
| 412 | typedef typename TypeOneEraser<L1, Head>::HeadType L2;
|
| 413 | public:
|
| 414 | typedef TypeList<Head, L2> HeadType;
|
| 415 | }; |
| 416 | |
| 417 | |
| 418 | template <class Head, class T, class R> |
| 419 | struct TypeOneReplacer;
|
| 420 | /// TypeOneReplacer replaces the first occurence
|
| 421 | /// of the type T in Head with type R.
|
| 422 | /// Usage:
|
| 423 | ///
|
| 424 | /// typedef TypeListType<char, int, float, int>::HeadType Type4;
|
| 425 | /// typedef TypeOneReplacer<Type4, int, double>::HeadType TypeR;
|
| 426 | /// (TypeR is a TypeList of char,double,float,int)
|
| 427 | ///
|
| 428 | |
| 429 | |
| 430 | template <class T, class R> |
| 431 | struct TypeOneReplacer<NullTypeList, T, R>
|
| 432 | {
|
| 433 | typedef NullTypeList HeadType;
|
| 434 | }; |
| 435 | |
| 436 | |
| 437 | template <class T, class Tail, class R> |
| 438 | struct TypeOneReplacer<TypeList<T, Tail>, T, R>
|
| 439 | {
|
| 440 | typedef TypeList<R, Tail> HeadType;
|
| 441 | }; |
| 442 | |
| 443 | |
| 444 | template <class Head, class Tail, class T, class R> |
| 445 | struct TypeOneReplacer<TypeList<Head, Tail>, T, R>
|
| 446 | {
|
| 447 | typedef TypeList<Head, typename TypeOneReplacer<Tail, T, R>::HeadType> HeadType;
|
| 448 | }; |
| 449 | |
| 450 | |
| 451 | template <class Head, class T, class R> |
| 452 | struct TypeAllReplacer;
|
| 453 | /// TypeAllReplacer replaces all the occurences
|
| 454 | /// of the type T in Head with type R.
|
| 455 | /// Usage:
|
| 456 | ///
|
| 457 | /// typedef TypeListType<char, int, float, int>::HeadType Type4;
|
| 458 | /// typedef TypeAllReplacer<Type4, int, double>::HeadType TypeR;
|
| 459 | /// (TypeR is a TypeList of char,double,float,double)
|
| 460 | ///
|
| 461 | |
| 462 | |
| 463 | template <class T, class R> |
| 464 | struct TypeAllReplacer<NullTypeList, T, R>
|
| 465 | {
|
| 466 | typedef NullTypeList HeadType;
|
| 467 | }; |
| 468 | |
| 469 | |
| 470 | template <class T, class Tail, class R> |
| 471 | struct TypeAllReplacer<TypeList<T, Tail>, T, R>
|
| 472 | {
|
| 473 | typedef TypeList<R, typename TypeAllReplacer<Tail, T, R>::HeadType> HeadType;
|
| 474 | }; |
| 475 | |
| 476 | |
| 477 | template <class Head, class Tail, class T, class R> |
| 478 | struct TypeAllReplacer<TypeList<Head, Tail>, T, R>
|
| 479 | {
|
| 480 | typedef TypeList<Head, typename TypeAllReplacer<Tail, T, R>::HeadType> HeadType;
|
| 481 | }; |
| 482 | |
| 483 | |
| 484 | } // namespace Poco
|
| 485 | |
| 486 | |
| 487 | #endif
|
