go home Home | Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages
TypeList.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright UMC Utrecht and contributors
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 // Denis P. Shamonin remarks:
19 // This file was copied from the ITKSimple, located in
20 // SimpleITK\src\Code\Common\include\Ancillary\TypeList.h
21 // Also missing original Loki classes was restored such as:
22 // (Erase, Replace, NoDuplicates, Reverse).
23 // Additionally classes VisitDimension and DualVisitDimension was added.
24 /*=========================================================================
25 *
26 * Copyright Insight Software Consortium
27 *
28 * Licensed under the Apache License, Version 2.0 (the "License");
29 * you may not use this file except in compliance with the License.
30 * You may obtain a copy of the License at
31 *
32 * http://www.apache.org/licenses/LICENSE-2.0.txt
33 *
34 * Unless required by applicable law or agreed to in writing, software
35 * distributed under the License is distributed on an "AS IS" BASIS,
36 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37 * See the License for the specific language governing permissions and
38 * limitations under the License.
39 *
40 *=========================================================================*/
41 // This file is based off of the work done in the Loki library but is
42 // substantially modified. It's a good book buy it.
43 //
45 // The Loki Library
46 // Copyright (c) 2001 by Andrei Alexandrescu
47 // This code accompanies the book:
48 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
49 // Patterns Applied". Copyright (c) 2001. Addison-Wesley.
50 // Permission to use, copy, modify, distribute and sell this software for any
51 // purpose is hereby granted without fee, provided that the above copyright
52 // notice appear in all copies and that both that copyright notice and this
53 // permission notice appear in supporting documentation.
54 // The author or Addison-Welsey Longman make no representations about the
55 // suitability of this software for any purpose. It is provided "as is"
56 // without express or implied warranty.
58 
59 #ifndef __TypeList_H__
60 #define __TypeList_H__
61 
62 #if defined( __clang__ )
63 #define CLANG_TEMPLATE template
64 #else
65 #define CLANG_TEMPLATE
66 #endif
67 
68 namespace typelist
69 {
70 
81 template< typename H, typename T >
82 struct TypeList
83 {
84  typedef H Head;
85  typedef T Tail;
86 };
87 
91 struct NullType {};
92 
108 template
109 <
110 typename T1 = NullType, typename T2 = NullType, typename T3 = NullType,
111 typename T4 = NullType, typename T5 = NullType, typename T6 = NullType,
112 typename T7 = NullType, typename T8 = NullType, typename T9 = NullType,
113 typename T10 = NullType, typename T11 = NullType, typename T12 = NullType,
114 typename T13 = NullType, typename T14 = NullType, typename T15 = NullType,
115 typename T16 = NullType, typename T17 = NullType, typename T18 = NullType,
116 typename T19 = NullType, typename T20 = NullType, typename T21 = NullType,
117 typename T22 = NullType, typename T23 = NullType, typename T24 = NullType
118 >
120 {
121 private:
122 
123  typedef typename MakeTypeList
124  <
125  T2, T3, T4,
126  T5, T6, T7,
127  T8, T9, T10,
128  T11, T12, T13,
129  T14, T15, T16,
130  T17, T18, T19,
131  T20, T21, T22,
132  T23, T24
134 
135 public:
136 
138 };
139 template< >
140 struct MakeTypeList< >
141 {
142  typedef NullType Type;
143 };
144 
145 template< typename TTypeList >
146 struct Length;
159 template< typename H, typename T >
160 struct Length< TypeList< H, T > >
161 {
162  enum { Type = 1 + Length< T >::Type };
163 };
164 
166 template< >
167 struct Length< NullType >
168 {
169  enum { Type = 0 };
170 };
187 template< class TTypeList, unsigned int index >
188 struct TypeAt;
189 
190 template< class Head, class Tail >
191 struct TypeAt< TypeList< Head, Tail >, 0 >
192 {
193  typedef Head Type;
194 };
195 
196 template< class Head, class Tail, unsigned int i >
197 struct TypeAt< TypeList< Head, Tail >, i >
198 {
199  typedef typename TypeAt< Tail, i - 1 >::Type Type;
200 };
201 
202 template< unsigned int i >
203 struct TypeAt< NullType, i >
204 {
205  typedef NullType Type;
206 };
207 
208 template< class TTypeList1, class TTypeList2 >
209 struct Append;
231 template< class Head, class Tail, class T >
232 struct Append< TypeList< Head, Tail >, T >
233 {
235 };
236 
238 template< >
239 struct Append< NullType, NullType >
240 {
241  typedef NullType Type;
242 };
243 template< class T >
244 struct Append< NullType, T >
245 {
246  typedef TypeList< T, NullType > Type;
247 };
248 template< class T >
249 struct Append< T, NullType >
250 {
251  typedef TypeList< T, NullType > Type;
252 };
253 template< class Head, class Tail >
254 struct Append< NullType, TypeList< Head, Tail > >
255 {
256  typedef TypeList< Head, Tail > Type;
257 };
258 template< class Head, class Tail >
259 struct Append< TypeList< Head, Tail >, NullType >
260 {
261  typedef TypeList< Head, Tail > Type;
262 };
263 
267 template< class TList, class T >
268 struct Erase;
269 
270 template< class T >
271 struct Erase< NullType, T >
272 {
273  typedef NullType Type;
274 };
275 
276 template< class T, class Tail >
277 struct Erase< TypeList< T, Tail >, T >
278 {
279  typedef Tail Type;
280 };
281 
282 template< class Head, class Tail, class T >
283 struct Erase< TypeList< Head, Tail >, T >
284 {
285  typedef TypeList< Head, typename Erase< Tail, T >::Type > Type;
286 };
287 
291 template< class TList, class T >
292 struct EraseAll;
293 template< class T >
294 struct EraseAll< NullType, T >
295 {
296  typedef NullType Type;
297 };
298 template< class T, class Tail >
299 struct EraseAll< TypeList< T, Tail >, T >
300 {
301  typedef typename EraseAll< Tail, T >::Type Type;
302 };
303 template< class Head, class Tail, class T >
304 struct EraseAll< TypeList< Head, Tail >, T >
305 {
306  typedef TypeList< Head, typename EraseAll< Tail, T >::Type > Type;
307 };
308 
312 template< class TList >
313 struct NoDuplicates;
314 
315 template< >
316 struct NoDuplicates< NullType >
317 {
318  typedef NullType Type;
319 };
320 
321 template< class Head, class Tail >
322 struct NoDuplicates< TypeList< Head, Tail > >
323 {
324 private:
325 
326  typedef typename NoDuplicates< Tail >::Type L1;
327  typedef typename Erase< L1, Head >::Type L2;
328 
329 public:
330 
331  typedef TypeList< Head, L2 > Type;
332 };
333 
337 template< class TList, class T, class U >
338 struct Replace;
339 
340 template< class T, class U >
341 struct Replace< NullType, T, U >
342 {
343  typedef NullType Type;
344 };
345 
346 template< class T, class Tail, class U >
347 struct Replace< TypeList< T, Tail >, T, U >
348 {
349  typedef TypeList< U, Tail > Type;
350 };
351 
352 template< class Head, class Tail, class T, class U >
353 struct Replace< TypeList< Head, Tail >, T, U >
354 {
355  typedef TypeList< Head, typename Replace< Tail, T, U >::Type > Type;
356 };
357 
361 template< class TList, class T, class U >
362 struct ReplaceAll;
363 
364 template< class T, class U >
365 struct ReplaceAll< NullType, T, U >
366 {
367  typedef NullType Type;
368 };
369 
370 template< class T, class Tail, class U >
371 struct ReplaceAll< TypeList< T, Tail >, T, U >
372 {
373  typedef TypeList< U, typename ReplaceAll< Tail, T, U >::Type > Type;
374 };
375 
376 template< class Head, class Tail, class T, class U >
377 struct ReplaceAll< TypeList< Head, Tail >, T, U >
378 {
379  typedef TypeList< Head, typename ReplaceAll< Tail, T, U >::Type > Type;
380 };
381 
385 template< class TList >
386 struct Reverse;
387 
388 template< >
389 struct Reverse< NullType >
390 {
391  typedef NullType Type;
392 };
393 
394 template< class Head, class Tail >
395 struct Reverse< TypeList< Head, Tail > >
396 {
397  typedef typename Append< typename Reverse< Tail >::Type, Head >::Type Type;
398 };
399 
414 template< class TTypeList, class TType >
415 struct IndexOf;
416 template< class TType >
417 struct IndexOf< NullType, TType >
418 {
419  enum { Type = -1 };
420 };
421 template< class TType, class TTail >
422 struct IndexOf< TypeList< TType, TTail >, TType >
423 {
424  enum { Type = 0 };
425 };
426 template< class Head, class TTail, class TType >
427 struct IndexOf< TypeList< Head, TTail >, TType >
428 {
429 private:
430 
432 
433 public:
434 
435  enum { Type = ( temp == -1 ? -1 : 1 + temp ) };
436 };
437 
450 template< class TTypeList, class TType >
451 struct HasType;
452 template< class TType >
453 struct HasType< NullType, TType >
454 {
455  enum { Type = false };
456 };
457 template< class TType, class TTail >
458 struct HasType< TypeList< TType, TTail >, TType >
459 {
460  enum { Type = true };
461 };
462 template< class Head, class TTail, class TType >
463 struct HasType< TypeList< Head, TTail >, TType >
464 {
466 };
467 
486 template< class TTypeList >
487 struct Visit
488 {
489  template< class Predicate >
490  void operator()( Predicate & visitor )
491  {
492  typedef typename TTypeList::Head Head;
493  typedef typename TTypeList::Tail Tail;
494  visitor.CLANG_TEMPLATE operator()< Head >( );
495  Visit< Tail > next;
496  next.CLANG_TEMPLATE operator()< Predicate >( visitor );
497  }
498 
499 
500  template< class Predicate >
501  void operator()( const Predicate & visitor )
502  {
503  typedef typename TTypeList::Head Head;
504  typedef typename TTypeList::Tail Tail;
505  visitor.CLANG_TEMPLATE operator()< Head >( );
506  Visit< Tail > next;
507  next.CLANG_TEMPLATE operator()< Predicate >( visitor );
508  }
509 
510 
511 };
512 
513 template< >
514 struct Visit< NullType >
515 {
516  template< class Predicate >
517  void operator()( const Predicate & )
518  {}
519 };
520 
537 template< class TTypeList, unsigned int Dimension >
539 {
540  template< class Predicate >
541  void operator()( Predicate & visitor )
542  {
543  typedef typename TTypeList::Head Head;
544  typedef typename TTypeList::Tail Tail;
545  visitor.CLANG_TEMPLATE operator()< Head, Dimension >( );
547  next.CLANG_TEMPLATE operator()< Predicate >( visitor );
548  }
549 
550 
551  template< class Predicate >
552  void operator()( const Predicate & visitor )
553  {
554  typedef typename TTypeList::Head Head;
555  typedef typename TTypeList::Tail Tail;
556  visitor.CLANG_TEMPLATE operator()< Head, Dimension >( );
558  next.CLANG_TEMPLATE operator()< Predicate >( visitor );
559  }
560 
561 
562 };
563 
564 template< unsigned int Dimension >
565 struct VisitDimension< NullType, Dimension >
566 {
567  template< class Predicate >
568  void operator()( const Predicate & )
569  {}
570 };
571 
590 template< typename TLeftTypeList, typename TRightTypeList >
592 
593 template< typename TLeftTypeList, typename TRightTypeList >
594 struct DualVisit
595 {
596 
597  template< typename Visitor >
598  void operator()( Visitor & visitor ) const
599  {
601  return impl.CLANG_TEMPLATE operator()< Visitor >( visitor );
602  }
603 
604 
605  template< typename Visitor >
606  void operator()( const Visitor & visitor ) const
607  {
609  return impl.CLANG_TEMPLATE operator()< Visitor >( visitor );
610  }
611 
612 
613 };
614 
628 template< typename TLeftTypeList, typename TRightTypeList >
629 struct DualVisitImpl
630 {
631  template< typename Visitor >
632  void operator()( Visitor & visitor ) const
633  {
634  typedef typename TLeftTypeList::Tail LeftTail;
635 
636  DualVisitImpl< TLeftTypeList, TRightTypeList > goRight;
637  goRight.visitRHS< Visitor >( visitor );
638 
639  DualVisitImpl< LeftTail, TRightTypeList > goLeft;
640  goLeft.CLANG_TEMPLATE operator()< Visitor >( visitor );
641  }
642 
643 
644  template< typename Visitor >
645  void operator()( const Visitor & visitor ) const
646  {
647  typedef typename TLeftTypeList::Tail LeftTail;
648 
649  DualVisitImpl< TLeftTypeList, TRightTypeList > goRight;
650  goRight.visitRHS< Visitor >( visitor );
651 
652  DualVisitImpl< LeftTail, TRightTypeList > goLeft;
653  goLeft.CLANG_TEMPLATE operator()< Visitor >( visitor );
654  }
655 
656 
657  template< typename Visitor >
658  void visitRHS( Visitor & visitor ) const
659  {
660  typedef typename TLeftTypeList::Head LeftHead;
661  typedef typename TRightTypeList::Head RightHead;
662  typedef typename TRightTypeList::Tail RightTail;
663 
664  visitor.CLANG_TEMPLATE operator()< LeftHead, RightHead >( );
665 
666  DualVisitImpl< TLeftTypeList, RightTail > goRight;
667  goRight.CLANG_TEMPLATE visitRHS< Visitor >( visitor );
668  }
669 
670 
671  template< typename Visitor >
672  void visitRHS( const Visitor & visitor ) const
673  {
674  typedef typename TLeftTypeList::Head LeftHead;
675  typedef typename TRightTypeList::Head RightHead;
676  typedef typename TRightTypeList::Tail RightTail;
677 
678  visitor.CLANG_TEMPLATE operator()< LeftHead, RightHead >( );
679 
680  DualVisitImpl< TLeftTypeList, RightTail > goRight;
681  goRight.CLANG_TEMPLATE visitRHS< Visitor >( visitor );
682  }
683 
684 
685 };
686 
687 template< typename TRightTypeList >
688 struct DualVisitImpl< typelist::NullType, TRightTypeList >
689 {
690  template< typename Visitor >
691  void operator()( const Visitor & ) const
692  {}
693 };
694 template< typename TLeftTypeList >
695 struct DualVisitImpl< TLeftTypeList, typelist::NullType >
696 {
697  template< typename Visitor >
698  void operator()( const Visitor & ) const
699  {}
700 
701  template< typename Visitor >
702  void visitRHS( const Visitor & ) const {}
703 };
704 
705 template< >
706 struct DualVisitImpl< typelist::NullType, typelist::NullType >
707 {
708  template< typename Visitor >
709  void operator()( const Visitor & ) const
710  {}
711 };
712 
733 template< typename TLeftTypeList, typename TRightTypeList, unsigned int Dimension >
734 struct DualVisitDimensionImpl;
735 
736 template< typename TLeftTypeList, typename TRightTypeList, unsigned int Dimension >
737 struct DualVisitDimension
738 {
739 
740  template< typename Visitor >
741  void operator()( Visitor & visitor ) const
742  {
743  DualVisitDimensionImpl< TLeftTypeList, TRightTypeList, Dimension > impl;
744  return impl.CLANG_TEMPLATE operator()< Visitor >( visitor );
745  }
746 
747 
748  template< typename Visitor >
749  void operator()( const Visitor & visitor ) const
750  {
751  DualVisitDimensionImpl< TLeftTypeList, TRightTypeList, Dimension > impl;
752  return impl.CLANG_TEMPLATE operator()< Visitor >( visitor );
753  }
754 
755 
756 };
757 
771 template< typename TLeftTypeList, typename TRightTypeList, unsigned int Dimension >
772 struct DualVisitDimensionImpl
773 {
774  template< typename Visitor >
775  void operator()( Visitor & visitor ) const
776  {
777  typedef typename TLeftTypeList::Tail LeftTail;
778 
779  DualVisitDimensionImpl< TLeftTypeList, TRightTypeList, Dimension > goRight;
780  goRight.visitRHS< Visitor >( visitor );
781 
782  DualVisitDimensionImpl< LeftTail, TRightTypeList, Dimension > goLeft;
783  goLeft.CLANG_TEMPLATE operator()< Visitor >( visitor );
784  }
785 
786 
787  template< typename Visitor >
788  void operator()( const Visitor & visitor ) const
789  {
790  typedef typename TLeftTypeList::Tail LeftTail;
791 
792  DualVisitDimensionImpl< TLeftTypeList, TRightTypeList, Dimension > goRight;
793  goRight.visitRHS< Visitor >( visitor );
794 
795  DualVisitDimensionImpl< LeftTail, TRightTypeList, Dimension > goLeft;
796  goLeft.CLANG_TEMPLATE operator()< Visitor >( visitor );
797  }
798 
799 
800  template< typename Visitor >
801  void visitRHS( Visitor & visitor ) const
802  {
803  typedef typename TLeftTypeList::Head LeftHead;
804  typedef typename TRightTypeList::Head RightHead;
805  typedef typename TRightTypeList::Tail RightTail;
806 
807  visitor.CLANG_TEMPLATE operator()< LeftHead, RightHead, Dimension >( );
808 
809  DualVisitDimensionImpl< TLeftTypeList, RightTail, Dimension > goRight;
810  goRight.CLANG_TEMPLATE visitRHS< Visitor >( visitor );
811  }
812 
813 
814  template< typename Visitor >
815  void visitRHS( const Visitor & visitor ) const
816  {
817  typedef typename TLeftTypeList::Head LeftHead;
818  typedef typename TRightTypeList::Head RightHead;
819  typedef typename TRightTypeList::Tail RightTail;
820 
821  visitor.CLANG_TEMPLATE operator()< LeftHead, RightHead, Dimension >( );
822 
823  DualVisitDimensionImpl< TLeftTypeList, RightTail, Dimension > goRight;
824  goRight.CLANG_TEMPLATE visitRHS< Visitor >( visitor );
825  }
826 
827 
828 };
829 
830 template< typename TRightTypeList, unsigned int Dimension >
831 struct DualVisitDimensionImpl< typelist::NullType, TRightTypeList, Dimension >
832 {
833  template< typename Visitor >
834  void operator()( const Visitor & ) const
835  {}
836 };
837 template< typename TLeftTypeList, unsigned int Dimension >
838 struct DualVisitDimensionImpl< TLeftTypeList, typelist::NullType, Dimension >
839 {
840  template< typename Visitor >
841  void operator()( const Visitor & ) const
842  {}
843 
844  template< typename Visitor >
845  void visitRHS( const Visitor & ) const {}
846 };
847 
848 template< unsigned int Dimension >
849 struct DualVisitDimensionImpl< typelist::NullType, typelist::NullType, Dimension >
850 {
851  template< typename Visitor >
852  void operator()( const Visitor & ) const
853  {}
854 };
855 
858 }
859 
860 #endif // __TypeList_H__
TypeList< Head, typename Append< Tail, T >::Type > Type
Definition: TypeList.h:234
void operator()(const Predicate &visitor)
Definition: TypeList.h:552
TypeList< T1, TailType > Type
Definition: TypeList.h:137
void operator()(Predicate &visitor)
Definition: TypeList.h:490
Finds the type at a given index in a typelist.
Definition: TypeList.h:188
Runs a templated predicate on each combination of the types on the two lists.
Definition: TypeList.h:594
Appends a type or a typelist to another.
Definition: TypeList.h:209
Runs a templated predicate on each type in the list.
Definition: TypeList.h:487
a empty type to indicate end of list
Definition: TypeList.h:91
The building block of typelists of any length.
Definition: TypeList.h:82
void operator()(const Predicate &visitor)
Definition: TypeList.h:501
void operator()(Visitor &visitor) const
Definition: TypeList.h:598
Finds the index of a type in a typelist.
Definition: TypeList.h:415
Generates a TypeList from it's template arguments.
Definition: TypeList.h:119
Queries the typelist for a type.
Definition: TypeList.h:451
Computes the length of a typelist.
Definition: TypeList.h:146
Runs a templated predicate on each type in the list with dimension provided as template parameter...
Definition: TypeList.h:538
void operator()(const Predicate &)
Definition: TypeList.h:517
void operator()(Predicate &visitor)
Definition: TypeList.h:541
MakeTypeList< T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24 >::Type TailType
Definition: TypeList.h:133
void operator()(const Visitor &visitor) const
Definition: TypeList.h:606


Generated on 04-09-2015 for elastix by doxygen 1.8.9.1 elastix logo